--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/greenlet/patches/01-slp_switch-sparc-multi-thread.patch Mon Mar 31 16:44:02 2014 -0700
@@ -0,0 +1,80 @@
+The following patch comes from the upstream 0.4.2 distribution and
+addresses the stated problem. It will be removed here once we update to
+a later version of greenlet.
+
+commit 3b03825089384f86842032ec1476ad3031908d43
+Author: Floris Bruynooghe <[email protected]>
+Date: Mon Sep 2 10:25:14 2013 +0100
+
+ Fix slp_switch on SPARC for multi-threaded environments
+
+ The CLEAN_WINDOWS trap was wrongly removed previously. It is not
+ required in a single-threaded environment but does need to be present
+ for the switching code to not mess up the register windows in a multi-
+ threaded environment.
+
+diff --git a/platform/switch_sparc_sun_gcc.h b/platform/switch_sparc_sun_gcc.h
+index 1f701a2..5c67205 100644
+--- a/platform/switch_sparc_sun_gcc.h
++++ b/platform/switch_sparc_sun_gcc.h
+@@ -2,6 +2,11 @@
+ * this is the internal transfer function.
+ *
+ * HISTORY
++ * 30-Aug-13 Floris Bruynooghe <[email protected]>
++ Clean the register windows again before returning.
++ This does not clobber the PIC register as it leaves
++ the current window intact and is required for multi-
++ threaded code to work correctly.
+ * 08-Mar-11 Floris Bruynooghe <[email protected]>
+ * No need to set return value register explicitly
+ * before the stack and framepointer are adjusted
+@@ -28,7 +33,8 @@
+
+
+ #define STACK_MAGIC 0
+-#define ST_FLUSH_WINDOWS 3
++#define ST_FLUSH_WINDOWS 0x03
++#define ST_CLEAN_WINDOWS 0x04
+
+ static int
+ slp_switch(void)
+@@ -37,7 +43,17 @@ slp_switch(void)
+
+ /* Flush SPARC register windows onto the stack, so they can be used to
+ * restore the registers after the stack has been switched out and
+- * restored. Then put the stack pointer into stackref. */
++ * restored. This also ensures the current window (pointed at by
++ * the CWP register) is the only window left in the registers
++ * (CANSAVE=0, CANRESTORE=0), that means the registers of our
++ * caller are no longer there and when we return they will always
++ * be loaded from the stack by a window underflow/fill trap.
++ *
++ * On SPARC v9 and above it might be more efficient to use the
++ * FLUSHW instruction instead of TA ST_FLUSH_WINDOWS. But that
++ * requires the correct -mcpu flag to gcc.
++ *
++ * Then put the stack pointer into stackref. */
+ __asm__ volatile (
+ "ta %1\n\t"
+ "mov %%sp, %0"
+@@ -57,11 +73,13 @@ slp_switch(void)
+ /* Copy new stack from it's save store on the heap */
+ SLP_RESTORE_STATE();
+
+- /* No need to restore any registers from the stack nor clear them: the
+- * frame pointer has just been set and the return value register is
+- * also being set by the return statement below. After returning a
+- * restore instruction is given and the frame below us will load all
+- * it's registers using a fill_trap if required. */
++ /* No need to set the return value register, the return
++ * statement below does this just fine. After returning a restore
++ * instruction is given and a fill-trap will load all the registers
++ * from the stack if needed. However in a multi-threaded environment
++ * we can't guarantee the other register windows are fine to use by
++ * their threads anymore, so tell the CPU to clean them. */
++ __asm__ volatile ("ta %0" : : "i" (ST_CLEAN_WINDOWS));
+
+ return 0;
+ }
+