diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index f506f60..b123136 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -679,7 +679,11 @@ func (ctxt *Link) FixedFrameSize() int64 {
 	case sys.PPC64:
 		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
 		// just use that much stack always on ppc64x.
-		return int64(4 * ctxt.Arch.PtrSize)
+		if ctxt.Arch.Name == "ppc64le" {
+			return int64(4 * ctxt.Arch.PtrSize)
+		} else {
+			return int64(6 * ctxt.Arch.PtrSize)
+		}
 	default:
 		return int64(ctxt.Arch.PtrSize)
 	}
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index 60b6491..a2579db 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -261,9 +261,6 @@ func determineLinkMode(ctxt *Link) {
 			} else {
 				ctxt.LinkMode = LinkInternal
 			}
-			if objabi.GOARCH == "ppc64" && objabi.GOOS != "aix" && ctxt.LinkMode == LinkExternal {
-				Exitf("external linking is not supported for %s/ppc64", objabi.GOOS)
-			}
 		}
 	case LinkInternal:
 		if needed, reason := mustLinkExternal(ctxt); needed {
diff --git a/src/runtime/asm_ppc64x.h b/src/runtime/asm_ppc64x.h
index 5e55055..cc881d9 100644
--- a/src/runtime/asm_ppc64x.h
+++ b/src/runtime/asm_ppc64x.h
@@ -22,4 +22,4 @@
 // we only support PIC on ppc64le which has a minimum 32 bytes of stack frame,
 // and currently always use that much, PIC on ppc64 would need to use 48).
 
-#define FIXED_FRAME 32
+#define FIXED_FRAME 48
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index 0a89b57..f03fc48 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -2,19 +2,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build ppc64 ppc64le
+// +build ppc64le ppc64
 
 #include "go_asm.h"
 #include "go_tls.h"
 #include "funcdata.h"
 #include "textflag.h"
 #include "asm_ppc64x.h"
 
-#ifdef GOOS_aix
+#ifdef GOARCH_ppc64
 #define cgoCalleeStackSize 48
 #else
 #define cgoCalleeStackSize 32
 #endif
 
 TEXT runtime·rt0_go(SB),NOSPLIT,$0
 	// R1 = stack; R3 = argc; R4 = argv; R13 = C TLS base pointer
@@ -86,6 +91,10 @@ nocgo:
 	MOVDU	R0, -8(R1)
 	MOVDU	R0, -8(R1)
 	MOVDU	R0, -8(R1)
+
+	MOVDU	R0, -8(R1)
+	MOVDU	R0, -8(R1)
+
 	BL	runtime·newproc(SB)
 	ADD	$(16+FIXED_FRAME), R1
 
@@ -190,6 +199,10 @@ TEXT runtime·mcall(SB), NOSPLIT|NOFRAME, $0-8
 	MOVDU	R0, -8(R1)
 	MOVDU	R0, -8(R1)
 	MOVDU	R0, -8(R1)
+
+	MOVDU	R0, -8(R1)
+	MOVDU	R0, -8(R1)
+
 	BL	(CTR)
 	MOVD	24(R1), R2
 	BR	runtime·badmcall2(SB)
@@ -553,12 +566,12 @@ TEXT gosave<>(SB),NOSPLIT|NOFRAME,$0
 	BL	runtime·badctxt(SB)
 	RET
 
-#ifdef GOOS_aix
+#ifdef GOARCH_ppc64
 #define asmcgocallSaveOffset cgoCalleeStackSize + 8
 #else
 #define asmcgocallSaveOffset cgoCalleeStackSize
 #endif
 
 // func asmcgocall(fn, arg unsafe.Pointer) int32
 // Call fn(arg) on the scheduler stack,
 // aligned appropriately for the gcc ABI.
diff --git a/src/runtime/internal/sys/arch_ppc64.go b/src/runtime/internal/sys/arch_ppc64.go
index 8cde4e1..61cf0a9 100644
--- a/src/runtime/internal/sys/arch_ppc64.go
+++ b/src/runtime/internal/sys/arch_ppc64.go
@@ -11,6 +11,6 @@ const (
 	PCQuantum           = 4
 	Int64Align          = 8
-	MinFrameSize        = 32
+	MinFrameSize        = 48
 )
 
 type Uintreg uint64
diff --git a/src/runtime/rt0_linux_ppc64.s b/src/runtime/rt0_linux_ppc64.s
index 1265b15..0995ba1 100644
--- a/src/runtime/rt0_linux_ppc64.s
+++ b/src/runtime/rt0_linux_ppc64.s
@@ -18,6 +18,7 @@ TEXT _main<>(SB),NOSPLIT,$-8
 	// There is no TLS base pointer.
 	//
 	// TODO(austin): Support ABI v1 dynamic linking entry point
+	XOR R0,R0
 	MOVD	$runtime·rt0_go(SB), R12
 	MOVD	R12, CTR
 	MOVBZ	runtime·iscgo(SB), R5
