How to trap PCI config space access

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

How to trap PCI config space access

Post by sawdust »

Hi,
What is a good way to trap PCI config space access? If someone tries to read PCI config space for a particular device, I want to return invalid values.

My CPU is ADM Opteron.

TIA :)
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Don't map that particular device into virtual memory? Remember that the pci config space exists in physical memory only. You have the choice of what you expose to a user program.
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Post by sawdust »

Don't map that particular device into virtual memory
My experiment is different. Pl. assume that the device is already setup and someone is trying to access its config space.
exkor
Member
Member
Posts: 111
Joined: Wed May 23, 2007 9:38 pm

Post by exkor »

JamesM wrote:Remember that the pci config space exists in physical memory only.
And remeber that you can use I/O(inportp,outportb). The guy didn't say who, from where, how and with which privilege device gets accessed.
Not sure but think that up to PCI 2.2 devices are accessed only with I/O. (Would like to write enumeration thru memory someday)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: How to trap PCI config space access

Post by Brendan »

Hi,
sawdust wrote:What is a good way to trap PCI config space access? If someone tries to read PCI config space for a particular device, I want to return invalid values.
Using kernel API function/s for PCI configuration space access is a very good idea, because there's reentrancy problems (e.g. device driver #1 sets the "address" I/O port, then device driver #2 sets the "address" I/O port, then device driver #1 reads from the "data" I/O port and gets data from the wrong place). It's also good to have some abstraction, because there's 3 different ways to access PCI configuration space - "mechanism #1" and "mechanism #2" (which are similar but incompatible) and the new method introduced with PCI Express (where PCI configuration space is mapped into the physical address space and "mechanism #1" is used for backward compatability).

If you need to prevent device drivers from bypassing the kernel API functions and accessing PCI configuration space directly, then you need to control which I/O ports (and which parts of the physical address space) the device drivers, etc can access, and then give them no access to PCI configuration space.

In general this is impossible to do if device drivers run at CPL=0, because it's impossible to prevent any CPL=0 code from accessing any I/O ports (or anything else). Note: there are ways (e.g. write your own secure compiler and force people to use it, or use virtualisation) but they are extrememly difficult and time consuming to implement.

If device drivers don't run at CPL=0 then you can set IOPL and either use the I/O permission bitmap in the TSS or emulate I/O port instructions in the general protection fault handler, so that the kernel can control which I/O ports each device driver can access.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
sawdust
Member
Member
Posts: 51
Joined: Thu Dec 20, 2007 4:04 pm

Post by sawdust »

Brendan,
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?
TIA
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

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... :D

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). :roll:


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Awwwww! The poor little APM fairy! :bigcry:
And the curse of a thousand curse words? :shock:

Hehe! You've definitely got a talent for that, Brendan. I still think you should do a cost/benefit analysis before stripping the insulation off your wires, though.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Brendan wrote:Ok - time to be serious...
But I liked the story. :cry:
DeviOuS - what a stupid name
User avatar
lukem95
Member
Member
Posts: 536
Joined: Fri Aug 03, 2007 6:03 am
Location: Cambridge, UK

Post by lukem95 »

zaleschiemilgabriel wrote:
Brendan wrote:Ok - time to be serious...
But I liked the story. :cry:
same!
~ Lukem95 [ Cake ]
Release: 0.08b
Image
Post Reply