Issue
The following quote is from the "Understanding the Linux Kernel 3rd Edition" book:
When a User Mode process attempts to access an I/O port by means of an in or out instruction, the CPU may need to access an I/O Permission Bitmap stored in the TSS to verify whether the process is allowed to address the port.
More precisely, when a process executes an in or out I/O instruction in User Mode, the control unit performs the following operations:
It checks the 2-bit IOPL field in the eflags register. If it is set to 3, the control unit executes the I/O instructions. Otherwise, it performs the next check.
It accesses the tr register to determine the current TSS, and thus the proper I/O Permission Bitmap.
It checks the bit of the I/O Permission Bitmap corresponding to the I/O port specified in the I/O instruction. If it is cleared, the instruction is executed; otherwise, the control unit raises a “General protection” exception.
The following quote is also from the same book:
Although Linux doesn’t use hardware context switches, it is nonetheless forced to set up a TSS for each distinct CPU in the system.
Now if Linux only has one TSS structure for all processes (instead of each process having its own TSS structure), and we know that each process must have its own I/O Permission Bitmap, does that mean that when Linux schedule the execution to another process, Linux would change the value of the I/O Permission Bitmap in the only TSS structure the CPU uses to the value of the I/O Permission Bitmap of the process to be executed (which Linux presumably stores somewhere in kernel memory)?
Solution
Yes. From the same section of the book, it says:
The tss_struct structure describes the format of the TSS. As already mentioned in Chapter 2, the init_tss array stores one TSS for each CPU on the system. At each process switch, the kernel updates some fields of the TSS so that the corresponding CPU’s control unit may safely retrieve the information it needs. Thus, the TSS reflects the privilege of the current process on the CPU, but there is no need to maintain TSSs for processes when they’re not running.
In later versions of the kernel, init_tss
was renamed to cpu_tss
. The TSS structure of each processor is initialized in cpu_init, which is executed once per processor when booting the system.
When switching from one task to another, __switch_to_xtra
is called, which calls switch_to_bitmap, which simply copies the IO bitmap of the next task into the TSS structure of the processor on which it is scheduled to run next.
Related: How do Intel CPUs that use the ring bus topology decode and handle port I/O operations.
Answered By - Hadi Brais