What does it mean when code is executed in kernel or user mode?
A program running in this mode has full access to the underlying hardware. It can execute any CPU instruction, access any memory address and essentially do anything it wants.
User Mode Code executing in this mode is restricted to hardware modification via the OS's API. It cannot access the hardware directly at all.
The big advantage to this kind of separation is that when a program crashes running in user mode, it isn't always fatal. In fact, on modern systems, it usually isn't.
Check out Jeff's writeup. It's his usual good stuff.
The short answer is: it just tells you where programs are spending their time at.
For a longer answer, I'll explain this in two steps. First:
1. Entering kernel mode
Every regular code you write, runs in "user mode".
Programs can use libraries to do common tasks for them. This is also user mode code.
At some point, the program may require a core function from the system. For example:
- accessing file contents from disk
- reserving a part the free memory
- getting video frame from a webcam driver
- sending image data to the graphics card.
- sending a network packet.
This essential - close to hardware - functionality is part of the kernel. That's the central program behind everything on your computer. It manages everything programs need in order to function.
To use a function in the kernel, the program execution path literally makes a jump from User mode to Kernel code. The kernel does it's job, and folds the execution path back to user mode.
When a program spends a lot of time in kernel mode, it often means it's doing a lot of hardware related activity. For example, disk seeks or video streaming. The hardware could also be malfunctioning; making the processing slow and causing the program to spend an unusual amount of time in kernel space.
2 the difference
Code in kernel space is high performant. The other parts of the kernel can call it directly, and the code has direct access to every resource of the system, without any boundary checking. The switching between kernel/user mode is also an expensive operation, which is completely avoided by running everything in kernel code.
Inside the kernel however, there isn't much room for security checking, protection against crashes, or writing to the wrong parts of memory. These are services the kernel can provide to other programs. It tricks programs to believe the world looks different (programs live in a virtual, sandboxed/restricted environment) and therefore everything that comes in/out of programs can be translated and guarded.
The kernel itself can't have much protection because there is nothing behind it to protect it. It is the heart of the system, and when that stops, everything ends. You get a kernel panic, or on Windows, the famous BSOD.
That's also the risk of kernel based code, and the reason more subsystems with low performance requirements are being moved to userspace. Essential hardware related parts however, are typically kernel code which is not going to change any time soon.
It's the distinction of whether the currently executing code is allowed to interact directly with various pieces of hardware. Kernel mode code can write to device buses, change memory mappings, switch running processes, and so forth. User mode can do computation, and it can make system calls into the kernel to interact with the rest of the world.