Understanding User and Kernel Mode

Note: it seems the Visual C++ runtimes do call kernel32.RaiseException wich calls ntdll.RtlRaiseException which calls ntdll.ZwRaiseException, which eventually does do a switch to ring0.

Did you trace the code path for all exception handling, or did you just look up the referenced API calls?

The VC++ runtime might well switch to Ring 0 for some exceptions but that doesn’t mean this happens for all exceptions.