Understanding User and Kernel Mode

Actually, .NET exceptions are implemented in terms of SEH exceptions, which means that they do go on a trip through kernel mode. See http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx for Chris Brumme’s explanation.

And it’s not fair to say that ‘most’ drivers are moving to user mode. Things like fixed disk drivers are still fundamental to system operation and will stay in kernel mode. But USB devices (e.g. Windows Mobile device sync) are starting to move to user mode, and audio devices did in Windows Vista.

Throwing exceptions in application code has nothing to do with processor rings. It’s all the same ring anyway.

First and foremost, throwing exceptions is software architecture decision. In general, you throw them when something goes wrong, which is a point where you don’t really care if it takes a bit longer to display error message to the user.

That said, exceptions in .NET are slow as hell, and that might be why .NET programmers tend to use them less than, say, Java programmers. I once saw a speed benchmark comparing throwing exceptions in different languages, and .NET was 5 or 6 times slower than all other languages, including C++ and Java.

rim’s example will make your process run with SYSTEM credentials and will thus give you complete control of the system (SYSTEM has more privileges than any Administrator), but it doesn’t mean you’ll run in kernel mode. Wouldn’t even work, as Kernel/User mode are pretty different environments (you can’t do Win32 API calls from kernel mode, for instance).

Jeff: exception handling doesn’t necessarily take a detour through the kernel, it depends on your programming environment as well as stuff that’s project-specific. For C++ code, it typically won’t detour through the kernel, try tracing code in a debugger. Notice that kernel32.dll != kernel-mode code.

And throwing an exception in a programming language should never involve any hardware exceptions…

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.

Don’t have a copy of GCC installed on windows right now, but I think they’re using a different route without depending on OS support?

If anyone is wondering,

View Show Kernel Times

in the Performance tab does the trick.

What has throwing exceptions got to do with kernel vs user mode? Switching to kernel mode is done by a “trap” call (wich is strictly speaking an interupt that is handled by a kernel process/thread), using the terminology I was thaught in “Operating Systems” at school. A runtime exception in a highlevel language may be a trap call or an interrupt handled by some error handling code in the OS or interpreter when trying to read/write to protected memory etc. but an “exception” doesn’t need to involve kernel traps (I think)…

“User mode is clearly a net public good, but it comes at a cost. Transitioning between User and Kernel mode is expensive. Really expensive.”

  • Not always!
    Tip: Windows GUI methods are executed in kernel mode!

Most drivers are shunted to the User side of the fence these days,
with the notable exception of video card drivers, which need
bare-knuckle Kernel mode performance. But even that is changing; in
Windows Vista, video drivers are segmented into User and Kernel
sections. Perhaps that’s why gamers complain that Vista performs about
10 percent slower in games.

A good guess might be that the “real” driver is running in kernel mode, while DRM shenanigans tied to the driver are taking place in user mode.

“Windows GUI methods are executed in kernel mode!”

Which is why crashing the GUI can crash Windows …

Unix always seems to have had the policy of everything user mode unless absolutely required

Windows seems to have had the policy of … well none at all really user/kernel/whatever if it’s windows itself …?

Unix is another world. There are good structures and good communications across APIs Modules.

Windows are full of patches and hacks!

“his is what we extra-crashy-code-writing programmers like to call “progress””

Hey now, I never write crashy or buggy code…never!

:wink:

Good post, Jeff! Me too love user mode.

In User mode, the executing code has no ability to directly access
hardware or reference memory. Code running in user mode must delegate
to system APIs to access hardware or memory.

I can’t read memory without making an API call?

Hey Now Jeff,
I just learned some info about CPU modes (Kernel User).
Coding Horror Fan,
Catto

The problem with your article is that you imply that kernel mode is faster than user space because it has direct-access to hardware. This is wrong.

Sometimes PCI hardware can directly-access a memory region mapped to user process memory. Sometimes a user process can write directly to a memory region that is mapped to a PCI device’s onboard memory (i.e. video memory). In such cases the kernel is bypassed and is only used to setup the mappings or issue commands to start an I/O transfer.

For instance under UNIX, if your user process bypasses the kernel cache to write out a file(called Direct I/O under UNIX/Linux) using the write() system call, the kernel will start an I/O transfer to the filesystem such that the write data will be directly read from your process’s memory. The user space “hit” in performance is the latency of calling a kernel system call which involves a context switch.

Some people get all worked up on context switches because they are heavy, etc. But under Linux, the context switch time is less than ONE microsecond.

BTW, the TUX article you reference is really old. Nowadays no one uses tux because the Linux kernel added sendfile() syscall which takes a file from user-space and directly maps it to a socket resulting in zero-copy sending.

Great info. Thanks…

nice post

Thanks for writing about something that i can understand. Not that i’m complaining, 'cause i’m not that savvy with this stuff, but sometimes you have a habit of losing me somewhere in the middle of your posts. And it sucks big time.

Good post!

I never really understood the difference between kernel mode and user mode until reading the opening section of this post. Nice job of exposition, and thanks.

I vote plus one for the you-have-the-wrong-kind-of-exceptions crowd. Other than that, good article :slight_smile: