All gevent code written today assumes that between I/O events all actions will happen atomically with respect to the rest of the program. That means you can safely do any multi-step operation on a shared resource you want without issue. The second you want to run 2 gevent threads in parallel this guarantee goes out the window. Gevent could be modified for multicore suppor if Python got it, but that still breaks every piece of gevent code written today. This is the same problem Twisted and Tornado have.
That's entirely dependent on what the work being done is. It's typical for gevent users to use the built-in queue systems to pass messages between coroutines, similar to Erlang's actor model. I do t believe a lot of work would be required if gevent users stuck to this style, as gevents docs suggest.
The guarantees of the framework no longer exist when you want to do things in parallel. Sure, not every line of code using gevent would break from this, but that's not the point. Even people using queues are often still playing with shared resources, which would be unsafe in multicore still.