Hi,
sawdust wrote:Just now I looked in 'AMD Bios Dev manual' that an MSR could be used to trap config space access and generate an SMI (SmiOnRdEn). But I'm not sure how to implement an SMI handler. Any thoughts?
Sure...
Once upon a time there was nice little fairy called APM, who would handle things like power management and expect very little from others. An SMI from the chipset would wake up the APM fairy, and it'd do whatever it needed to do without bothering anyone, and in this way everything worked well (but the SMI sent the CPU/s into a special mode called SMM that only the APM fairy could use).
Then, along came a big hairy monster called ACPI. This monster is so messy that only the richest knights (and the most insane drunkards) are willing to go near it. The ACPI monster spends most of it's time asleep. To wake it up you need to cast the curse of a thousand curse words. Once it's awake, it eats the APM fairy. Then, when an SMI occurs it eats them too and spits out something called an SCI instead. The OS needs to handle these SCIs (which is a lot of work - it involves running through an obstacle course created by the ACPI monster whilst trying not to be crushed by the ACPI monsters giant tentacles).
Ok - time to be serious...
To get the chipset to generate an SMI you'd first have to make sure the chipset isn't already using the I/O port access trap/s for other purposes (like emulating PS/2 keyboard when a USB keyboard is present, or emulating a PIT when only HPET is present, etc). This alone means you must support USB, HPET, etc natively, so that emulation (for backward compatability purposes) isn't necessary.
Then you'd need to enable ACPI so that your code can get the SCI (instead of having APM handle the SMI). Then you'd need to support ACPI's AML code (which is an interpretted byte-code that does what APM used to do, and some other stuff), so that the computer still works (e.g. doesn't overheat because power management stopped working). After all this you could add your own code to detect if the I/O port trap caused the SCI (if the trap isn't used for something else) and emulate the I/O port access.
Finally, after years of work, it'd only work computers with modern AMD CPUs. AFAIK there's similar I/O port traps in Intel chipsets, but it's "chipset specific" (and not "CPU model" specific), so it'd be harder to setup. I'm also not sure how you'd go with other manufacturers (e.g. VIA's chipsets and CPUs).
Of course with device drivers running at CPL=0, a device driver could just disable your trap anyway, so it's only useful when it's not useful (ie. if device drivers can be trusted to do the right thing then the trap isn't necessary, and if device drivers can't be trusted to do the right thing then they can't be trusted to leave your trap alone).
Basically, if you trust device drivers then you don't need to trap PCI configuration space access or worry about them doing anything else that could be considered malicious, and you could run them at CPL=0 in kernel space (e.g. monolithic kernel). Otherwise, if you don't trust device drivers then you're screwed unless you run them at CPL=3 (e.g. micro-kernel).
So, the real question here is: do you trust the device drivers?
For me the answer is "no, I don't trust the device drivers". This is because (regardless of whether I like it or not) some companies will only provide binary device drivers (due to intellectual property reasons, patents, etc). Therefore I need to be prepared to handle anonymous binary blobs written by people I've never even met, and need a micro-kernel because I can't really trust these anonymous binary blobs.
For Linux the answer is "yes, we trust the device drivers", which is why they really need open source device drivers that actually can be trusted (not "anonymous binary blobs" that could smash their poor defenseless little kernel into millions of bits faster than you can blink).
Cheers,
Brendan