18143276 greenlet can crash with register window corruption on MP SPARC
authordavid.comay@oracle.com
Mon, 03 Mar 2014 04:03:28 -0800
changeset 1735 2c35e21b08a3
parent 1734 05c8bc3fb76c
child 1736 03b0c559040f
18143276 greenlet can crash with register window corruption on MP SPARC
components/python/greenlet/greenlet-PYVER.p5m
components/python/greenlet/patches/01-slp_switch-sparc-multi-thread.patch
components/python/greenlet/resolve.deps
--- a/components/python/greenlet/greenlet-PYVER.p5m	Mon Mar 03 03:25:22 2014 -0800
+++ b/components/python/greenlet/greenlet-PYVER.p5m	Mon Mar 03 04:03:28 2014 -0800
@@ -37,13 +37,15 @@
 set name=org.opensolaris.arc-caseid value=PSARC/2013/140
 set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
 file path=usr/include/python$(PYVER)/greenlet/greenlet.h
-file path=usr/lib/python$(PYVER)/vendor-packages/64/greenlet.so \
-    pkg.debug.depend.path=/usr/gcc/3.4/lib
+file path=usr/lib/python$(PYVER)/vendor-packages/64/greenlet.so
 file path=usr/lib/python$(PYVER)/vendor-packages/greenlet-$(COMPONENT_VERSION)-py$(PYVER).egg-info
-file path=usr/lib/python$(PYVER)/vendor-packages/greenlet.so \
-    pkg.debug.depend.path=/usr/gcc/3.4/lib
+file path=usr/lib/python$(PYVER)/vendor-packages/greenlet.so
 license greenlet.license license="MIT, PSFv2"
 
+# force the rename with an optional dependency on the old name
+depend type=optional \
+    fmri=library/python-2/greenlet-$(PYV)@0.4.1,5.12-5.12.0.0.0.41.0
+
 # force a dependency on the Python runtime
 depend type=require fmri=__TBD pkg.debug.depend.file=python$(PYVER) \
     pkg.debug.depend.path=usr/bin
@@ -51,7 +53,3 @@
 # force a dependency on the greenlet package
 depend type=require \
     fmri=library/python/greenlet@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
-
-# force the rename with an optional dependency on the old name
-depend type=optional \
-    fmri=library/python-2/greenlet-$(PYV)@0.4.1,5.12-5.12.0.0.0.41.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/greenlet/patches/01-slp_switch-sparc-multi-thread.patch	Mon Mar 03 04:03:28 2014 -0800
@@ -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;
+     }
+
--- a/components/python/greenlet/resolve.deps	Mon Mar 03 03:25:22 2014 -0800
+++ b/components/python/greenlet/resolve.deps	Mon Mar 03 04:03:28 2014 -0800
@@ -1,5 +1,3 @@
 runtime/python-26
 runtime/python-27
 system/library
-system/library/gcc-3-runtime
-system/library/gcc/gcc-c-runtime