I know James Molloy's tutorial has its issues, but I didn't find these mentioned on the list so I was wondering if it's OK to do things this way or not.
1. His code sets all gates as interrupt gates, including the first 32 reserved for CPU interrupts, which I imagine should be set as trap gates instead. According to the wiki, the difference between the two is minimal (automaticaly disabled and reenabled interrupts for interrupt gates but not for trap gates), but surely there's a good reason why trap gates are a separate type?
2. When setting a gate, his code explicitly always changes the DPL to ring 3, which according to my understanding means that usermode code can also trigger CPU and hardware interrupts in addition to software interrupts. This is bad right?
Questions about IDT
Re: Questions about IDT
No. You generally want to make everything into interrupt gates. This way, you have no window in which an interrupt storm can cause problems. You always start with IF=0. If you have a pre-emptible kernel, and you're handling a system call or interrupt, and you have enough kernel stack left over, and you're done saving your state and changing your context, then you can enable IF. This means, except for NMIs, double faults, and MCEs, when you see CS == Kernel CS on the stack in the interrupt handler, you can assume the rest of the context to be switched over as well (e.g. no "swapgs" necessary)DaviUnic wrote:1. His code sets all gates as interrupt gates, including the first 32 reserved for CPU interrupts, which I imagine should be set as trap gates instead. According to the wiki, the difference between the two is minimal (automaticaly disabled and reenabled interrupts for interrupt gates but not for trap gates), but surely there's a good reason why trap gates are a separate type?
I don't know why trap gates exist, but I never saw a use for them myself.
Depends. For the exceptions, I'd make all the entries without error code DPL 3. This way a softint will not confuse my code. Exceptions will usually be triggered by the CPU, so DPL doesn't matter, but some can be called from user code.DaviUnic wrote: 2. When setting a gate, his code explicitly always changes the DPL to ring 3, which according to my understanding means that usermode code can also trigger CPU and hardware interrupts in addition to software interrupts. This is bad right?
For interrupts that aren't syscalls, though, and for exceptions with error code, yeah, this is a problem.
Carpe diem!
Re: Questions about IDT
DaviUnic wrote:2. When setting a gate, his code explicitly always changes the DPL to ring 3, which according to my understanding means that usermode code can also trigger CPU and hardware interrupts in addition to software interrupts. This is bad right?
So, that config would let one implement system calls accessible from ring 3.CPU Manual wrote:The processor checks the DPL of the interrupt or trap gate only if an exception or interrupt is generated with an INT n, INT3, or INTO instruction. Here, the CPL must be less than or equal to the DPL of the gate. ...
For hardware-generated interrupts and processor-detected exceptions, the processor ignores the DPL of interrupt and trap gates.
#GP, #PF, etc etc and IRQs are unaffected by the int/trap gate DPL. But you may still try to invoke them with e.g. INT n, which is not a very good idea as the handler may be unnecessarily confused.