4

Based on my understanding, the CPU executes kernel code in kernel mode when an interrupt is fired (for example: system call, keyboard key pressed, etc.), but I am wondering if we can have a program that runs on its own (without an interrupt being fired that is) in kernel mode.

What I mean is: a process in user mode gets executed when the scheduler switch execution to it, but can we have a "process" that the scheduler switch execution to, but this "process" runs in kernel mode (not sure if we can call a program running in kernel mode a "process")?

3
  • 1
    You can make a kernel module which run a kernel thread. Mar 22, 2019 at 12:00
  • This is probably not what you’re looking for, but processes run in kernel mode whenever they make a system call. Mar 22, 2019 at 12:04
  • 1
    Also when a process run, it can switch between kernel mode and user mode, there's is no such thing called "process in the user mode", just "process". Although Linux has the concept of "kernel threads", but they're still processes, although they usually never switch to user mode and you can't create such process from user mode through normal API. Mar 22, 2019 at 12:06

1 Answer 1

9

In order to answer this question I first need to clarify a bit of terminology.

Virtual memory addresses are divided into user space and kernel space. On some architectures the two are both part of a single linear address space on other architectures the two are independent address spaces.

The CPU at any given time is operating in either user mode or kernel mode. In kernel mode it will have more privileges and it can for example read and write both user space and kernel space. Some CPUs have more privilege levels. AMD64 compatible CPUs for example have four privilege levels which the operating system can make use of though Linux only uses two.

When the CPU is running in user mode it can manipulate pointers pointing to kernel space, but if it tries to access the content pointed to by those pointers it will cause an exception. While running in user mode the CPU can only read, write, and execute bytes in user space and it may be subject to additional restrictions (for example memory mappings could be configured to not allow write and execute for the same range).

From user mode you can only get into kernel mode through exceptions or interrupts which causes execution to start from an address in kernel space previously configured by the kernel. Thus there is no direct way to get code in user space executing in kernel mode.

However it is possible for kernel code to jump to addresses in user space, it's just not a good idea to do so. If you are running with privileges to load kernel modules (which usually means running as root), then you could construct a module in user space memory then load it into the kernel and have it jump back to code in user space. But whatever you are trying to do, there is a better way to achieve it than this.

In Linux there is a concept known as kernel threads. Kernel threads differ from user threads in that they don't have user space. Those threads are always in kernel mode. For performance reasons the context switching can leave the current user space around when switching to a kernel thread thus if a kernel thread try to access user space (which would be a bug) it will access the user space of the most recent user thread to run.

In Linux a process is a group of one or more threads which share certain resources such as using the same user space between them. Linux is very flexible in allowing threads to choose which resources to share and which not to share.

7
  • 1
    Minor quibble: AMD64 dropped rings 1 and 2, so there are only two rings now (or three if you consider VMX & co to be ring -1). Mar 22, 2019 at 12:09
  • @kasperd I think that kernel threads is what I am looking for, but I have two questions: 1) do kernel threads run on their own (i.e. does the scheduler execute them) or do they only get executed when an interrupt is fired? 2) if the scheduler executes them, does the scheduler switches the CPU mode to kernel mode right before it executes a kernel thread, and switches the CPU mode to user mode right before it executes a user thread?
    – user343092
    Mar 22, 2019 at 14:24
  • 1
    @StephenKitt That's the first I have heard of that. Do you have a link to an official source for that information? It does sound plausible though, it would be in line with the other cleanup AMD did when designing AMD64.
    – kasperd
    Mar 22, 2019 at 21:52
  • @user343092 Interrupts and exceptions put the CPU in kernel mode when they happen. Scheduling always happens while in kernel mode and there is no fundamental difference between how kernel threads and user threads are scheduled. Most of the long running threads spend most of their life time sleeping, and they can only go to sleep while in kernel mode. So in some sense you could say that even user threads are in kernel mode most of their life.
    – kasperd
    Mar 22, 2019 at 22:01
  • 1
    @kasperd I read it here a long time ago, and thought that explained why Xen switched from ring 1/3 on i386 to ring 0/3 on amd64, but I read through the relevant chapters in the AMD64 Architecture Programmer’s Manual and nothing indicates rings 1/2 aren’t supported in long, 64-bit mode. So my statement above is probably wrong. Mar 23, 2019 at 8:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .