You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| 15:0 | 0xFFFF | Represents the limit field for this segment. Ignored in long mode, but best set to max value in case we support compatibility mode in the future. |
58
+
| 15:0 | 0xFFFF | Represents the limit field for this segment. |
59
59
| 31:16 | TSS address bits 15:0 | Contains the lowest 16 bits of the tss address. |
60
60
| 39:32 | TSS address bits 23:16 | Contains the next 8 bits of the tss address. |
61
-
| 47:40 | 0b10001001 | Sets the type of GDT descriptor, it's DPL (bits 45:46) to 0, marks it as present (bit 47). The rest of this magic value indicates it's a valid TSS descriptor. If curious as to how this value was created, see the manual or our section about the GDT.|
62
-
| 55:48 | 0b10000 | Additional fields for the TSS entry. This bit means the TSS is `available`, it's generally unused in long mode, but has some side effects if compatibility mode is enabled. |
61
+
| 47:40 | 0b10001001 | Sets the type of GDT descriptor, it's DPL (bits 45:46) to 0, marks it as present (bit 47). Bit 44 (S) along with bits 40 to 43 indicate the type of descriptor. If curious as to how this value was created, see the intel SDM manual or our section about the GDT.|
62
+
| 48:51 | Limit 16:9 | The higher part of the limit field, bits 9 to 16 |
63
+
| 55:52 | 0bG000A | Additional fields for the TSS entry. Where G (bit 55) is the granularity bit and A (bit 52) is a bit left available to the operating system. The other bits must be left as 0 |
63
64
| 63:56 | TSS address bits 31:24 | Contains the next 8 bits of the tss address. |
64
65
| 95:64 | TSS address bits 63:32 | Contains the upper 32 bits of the tss address. |
65
66
| 96:127 | Reserved | They should be left as 0. |
@@ -74,7 +75,7 @@ The `ltr` instruction (load task register) takes the byte offset into the GDT we
74
75
ltr $0x28
75
76
```
76
77
77
-
It's that simple! Now the cpu knows where to find our TSS. It's worth noting that you only need to reload the task register if the TSS has moved in memory. Ideally your TSS should never move, and so should only be loaded once. If the fields of the TSS are ever updated, the CPU will use the new values the next time it needs them, no need to reload TR.
78
+
It's that simple! Now the cpu knows where to find our TSS. It's worth noting that we only need to reload the task register if the TSS has moved in memory. Ideally it should never move, and so should only be loaded once. If the fields of the TSS are ever updated, the CPU will use the new values the next time it needs them, no need to reload TR.
78
79
79
80
### Putting It All Together
80
81
@@ -101,7 +102,7 @@ There's a few ways to go about this:
101
102
102
103
### Software Interrupts
103
104
104
-
On `x86(_64)` IDT entries have a 2-bit DPL field. The DPL (Descriptor Privilege Level) represents the highest ring that is allowed to call that interrupt from software. This is usually left to zero as default, meaning that ring 0 can use the `int` instruction to trigger an interrupt from software, but all rings higher than 0 will cause a a general protection fault. This means that user mode software (ring 3) will always trigger a #GP instead of being able to call an interrupt handler.
105
+
On `x86(_64)` IDT entries have a 2-bit DPL field. The DPL (Descriptor Privilege Level) represents the highest ring that is allowed to call that interrupt from software. This is usually left to zero as default, meaning that ring 0 can use the `int` instruction to trigger an interrupt from software, but all rings higher than 0 will cause a general protection fault. This means that user mode software (ring 3) will always trigger a #GP instead of being able to call an interrupt handler.
105
106
106
107
While this is a good default behaviour, as it stops a user program from being able to call the page fault handler for example, it presents a problem: without the use of dedicated instructions (which may not exist), how do we issue a system call?
0 commit comments