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?
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)
I don't know why trap gates exist, but I never saw a use for them myself.
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?
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.
For interrupts that aren't syscalls, though, and for exceptions with error code, yeah, this is a problem.