Langbahn Team – Weltmeisterschaft

Task state segment: Difference between revisions

Content deleted Content added
Wafulz (talk | contribs)
m bolding
AcidPenguin9873 (talk | contribs)
Some cleanup, clarifications, TSS descriptor can only be placed in the GDT
Line 10: Line 10:


== Location of the TSS ==
== Location of the TSS ==
The TSS may reside anywhere in [[memory]]. A special segment register called the [[Task Register]] (TR) holds a segment selector that points to a valid TSS segment descriptor which may reside in either the [[GDT]] or the [[LDT]]. Therefore, to use a TSS the following must be done by the operating system kernel:
The TSS may reside anywhere in [[memory]]. A special segment register called the [[Task Register]] (TR) holds a [[segment selector|memory segment]] that points to a valid TSS segment descriptor which resides in the [[GDT]] (a TSS descriptor may not reside in the [[LDT]]). Therefore, to use a TSS the following must be done by the operating system kernel:


1) Create a TSS descriptor entry in the GDT/LDT
# Create a TSS descriptor entry in the GDT
2) Load the TR register with a segment selector for that segment
# Load the TR register with a segment selector for that segment
3) Add information to the TSS in memory as needed
# Add information to the TSS in memory as needed


The TSS should be placed in memory that is accessible only to the [[kernel]] for security purposes.
The TSS should be placed in memory that is accessible only to the [[kernel]] for security purposes.


== Task Register ==
== Task Register ==
The TR register is a 16-bit register which holds a segment selector the TSS. It may be loaded through the [[LTR]] instruction. [[LTR]] is a privileged instruction and acts in a manner similar to other segment register loads.
The TR register is a 16-bit register which holds a segment selector for the TSS. It may be loaded through the [[LTR]] instruction. [[LTR]] is a privileged instruction and acts in a manner similar to other segment register loads.


== Architected Register State ==
== Architected Register State ==
Line 25: Line 25:


== I/O Port Permissions ==
== I/O Port Permissions ==
The TSS contains a 16-bit pointer to I/O port permissions for the current [[task]]. When a program issues an x86 I/O port instruction such as [[IN]] or [[OUT]] the hardware will do a privilege check. If the [[CPL]] of the program is numerically greater than the IOPL, the hardware will then check the I/O permissions in the TSS to see if that program can access the specific port in question. This feature allows operating systems to grant selective port access to user programs.
The TSS contains a 16-bit pointer to I/O port permissions bitmap for the current [[task]]. This bitmap, usually set up by the operating system when a task is started, specifies individual ports to which the program should have access. The I/O bitmap is a [[bit array]] of port access permissions; if the program has permission to access a port, a "1" is stored at the corresponding bit index, and if the program does not have permission, a "0" is stored there. The feature operates as follows: when a program issues an x86 I/O port instruction such as IN or OUT (see [[x86 instruction listings]]), the hardware will do an I/O privilege level (IOPL) check to see if the program has access to all I/O ports. If the [[CPL]] of the program is numerically greater than the IOPL (the program is less-privileged than what the IOPL specifies), the program does not have I/O port access to all ports. The hardware will then check the I/O permissions bitmap in the TSS to see if that program can access the specific port in the IN or OUT instruction. If the bit in the I/O port permissions bitmap is set, the program is allowed access to this port, and the instruction is allowed to execute. If the bit is clear, the program does not have access and the processor generates a [[General Protection Fault]]. This feature allows operating systems to grant selective port access to user programs.


== Inner Level Stack Pointers ==
== Inner Level Stack Pointers ==
The TSS contains 6 fields for specifying the new [[stack pointer]] when a privilege level change happens. The field SS0 contains the stack segment selector for CPL=0, while the field ESP0/RSP0 contains the new ESP/RSP value for CPL=0. Therefore, when an interrupt happens in protected (32-bit) mode, the [[x86]] CPU will look in the TSS for SS0 and ESP0 and load their values into SS and ESP respectively. This allows for the kernel to use a different stack than the user program, and also have this stack be unique for each user program.
The TSS contains 6 fields for specifying the new [[stack pointer]] when a privilege level change happens. The field SS0 contains the stack segment selector for CPL=0, and the field ESP0/RSP0 contains the new ESP/RSP value for CPL=0. When an interrupt happens in protected (32-bit) mode, the [[x86]] CPU will look in the TSS for SS0 and ESP0 and load their values into SS and ESP respectively. This allows for the kernel to use a different stack than the user program, and also have this stack be unique for each user program.


A new feature introduced in the [[AMD64]] extensions is called the Interrupt Stack Table (IST). This also resides in the TSS and contains logical (segment+offset) stack pointers. An [[interrupt descriptor]] may specify an IST entry to use (there are 8). If that is the case, the processor will load the new stack from the IST instead. This allows known good stacks to be used in case of serious errors ([[NMI]] or [[Double Fault]] for example).
A new feature introduced in the [[AMD64]] extensions is called the Interrupt Stack Table (IST). This also resides in the TSS and contains logical (segment+offset) stack pointers. An [[interrupt descriptor]] may specify an IST entry to use (there are 8). If that is the case, the processor will load the new stack from the IST instead. This allows known-good stacks to be used in case of serious errors ([[NMI]] or [[Double Fault]] for example).


== Previous TSS Link ==
== Previous TSS Link ==
Line 36: Line 36:


== Use of TSS in Linux ==
== Use of TSS in Linux ==
Although a TSS could be created for each task running on the computer, [[Linux]] only creates one and uses it for all tasks. Linux only uses the I/O port permission map and inner stack features of the TSS. The other features are only needed for hardware task switches which Linux does not use.
Although a TSS could be created for each task running on the computer, [[Linux]] only creates one and uses it for all tasks. Linux only uses the I/O port permission bitmap and inner stack features of the TSS. The other features are only needed for hardware task switches which Linux does not use.


== Exceptions related to the TSS ==
== Exceptions related to the TSS ==
The x86 [[exception]] vector 10 is called the Invalid TSS exception (#TS). It is issued by the processor whenever something goes wrong with the TSS access. For example, if an interrupt happens in CPL=3 and is transfering control to CPL=0 and the task register holds an bad TSS selector, a #TS fault will be generated. The Invalid TSS exception should never happen during normal operating system operation and is almost always related to a kernel bug.
The x86 [[exception]] vector 10 is called the Invalid TSS exception (#TS). It is issued by the processor whenever something goes wrong with the TSS access. For example, if an interrupt happens in CPL=3 and is transfering control to CPL=0, the TSS is used to extract SS0 and ESP0/RSP0 for the stack switch. If the task register holds an bad TSS selector, a #TS fault will be generated. The Invalid TSS exception should never happen during normal operating system operation and is almost always related to a kernel bug.


For more details on the TSS layout and usage, see chapter 6 of the [[IA-32]] manual.
For more details on the TSS layout and usage, see chapter 6 of the [[IA-32]] manual.

Revision as of 19:44, 6 August 2006

The Task State Segment is a special x86 structure which holds information about a task. It is used by the operating system kernel for task management. Specifically, the following information is stored in the TSS:

  • Architected register state
  • I/O Port permissions
  • Inner level stack pointers
  • Previous TSS link

All this information should be stored at specific locations within the TSS as specified in the IA-32 manuals.


Location of the TSS

The TSS may reside anywhere in memory. A special segment register called the Task Register (TR) holds a memory segment that points to a valid TSS segment descriptor which resides in the GDT (a TSS descriptor may not reside in the LDT). Therefore, to use a TSS the following must be done by the operating system kernel:

  1. Create a TSS descriptor entry in the GDT
  2. Load the TR register with a segment selector for that segment
  3. Add information to the TSS in memory as needed

The TSS should be placed in memory that is accessible only to the kernel for security purposes.

Task Register

The TR register is a 16-bit register which holds a segment selector for the TSS. It may be loaded through the LTR instruction. LTR is a privileged instruction and acts in a manner similar to other segment register loads.

Architected Register State

The TSS may contain saved values of all the x86 registers. This is used for task switching. The operating system may load the TSS with the values of the registers that the new task needs and after executing a hardware task switch (such as with an IRET instruction) the x86 CPU will load the saved values from the TSS into the appropriate registers. Note that some modern operating systems such as Linux do not use these fields in the TSS as they implement software task switching.

I/O Port Permissions

The TSS contains a 16-bit pointer to I/O port permissions bitmap for the current task. This bitmap, usually set up by the operating system when a task is started, specifies individual ports to which the program should have access. The I/O bitmap is a bit array of port access permissions; if the program has permission to access a port, a "1" is stored at the corresponding bit index, and if the program does not have permission, a "0" is stored there. The feature operates as follows: when a program issues an x86 I/O port instruction such as IN or OUT (see x86 instruction listings), the hardware will do an I/O privilege level (IOPL) check to see if the program has access to all I/O ports. If the CPL of the program is numerically greater than the IOPL (the program is less-privileged than what the IOPL specifies), the program does not have I/O port access to all ports. The hardware will then check the I/O permissions bitmap in the TSS to see if that program can access the specific port in the IN or OUT instruction. If the bit in the I/O port permissions bitmap is set, the program is allowed access to this port, and the instruction is allowed to execute. If the bit is clear, the program does not have access and the processor generates a General Protection Fault. This feature allows operating systems to grant selective port access to user programs.

Inner Level Stack Pointers

The TSS contains 6 fields for specifying the new stack pointer when a privilege level change happens. The field SS0 contains the stack segment selector for CPL=0, and the field ESP0/RSP0 contains the new ESP/RSP value for CPL=0. When an interrupt happens in protected (32-bit) mode, the x86 CPU will look in the TSS for SS0 and ESP0 and load their values into SS and ESP respectively. This allows for the kernel to use a different stack than the user program, and also have this stack be unique for each user program.

A new feature introduced in the AMD64 extensions is called the Interrupt Stack Table (IST). This also resides in the TSS and contains logical (segment+offset) stack pointers. An interrupt descriptor may specify an IST entry to use (there are 8). If that is the case, the processor will load the new stack from the IST instead. This allows known-good stacks to be used in case of serious errors (NMI or Double Fault for example).

This is a 16-bit selector which allows linking this TSS with the previous one. This is only used for hardware task switching. See the IA-32 manuals for details.

Use of TSS in Linux

Although a TSS could be created for each task running on the computer, Linux only creates one and uses it for all tasks. Linux only uses the I/O port permission bitmap and inner stack features of the TSS. The other features are only needed for hardware task switches which Linux does not use.

The x86 exception vector 10 is called the Invalid TSS exception (#TS). It is issued by the processor whenever something goes wrong with the TSS access. For example, if an interrupt happens in CPL=3 and is transfering control to CPL=0, the TSS is used to extract SS0 and ESP0/RSP0 for the stack switch. If the task register holds an bad TSS selector, a #TS fault will be generated. The Invalid TSS exception should never happen during normal operating system operation and is almost always related to a kernel bug.

For more details on the TSS layout and usage, see chapter 6 of the IA-32 manual.