diff options
author | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2011-12-18 14:34:42 +0000 |
---|---|---|
committer | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2011-12-18 14:34:42 +0000 |
commit | 32103e04bed97da5c42a12d2d40cbdfff61e8cdb (patch) | |
tree | 4bf75215cdf821c41f61f0950ba9887f334a19d7 /xen/arch/x86/traps.c | |
parent | f2271ccd4576e36a975a5648cee436b12e1d857a (diff) | |
download | xen-32103e04bed97da5c42a12d2d40cbdfff61e8cdb.tar.gz xen-32103e04bed97da5c42a12d2d40cbdfff61e8cdb.tar.bz2 xen-32103e04bed97da5c42a12d2d40cbdfff61e8cdb.zip |
xsm: add checks on PCI configuration access
PCI configuration access is allowed to any privileged domain
regardless of I/O port access restrictions; add XSM hooks for these
accesses.
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Diffstat (limited to 'xen/arch/x86/traps.c')
-rw-r--r-- | xen/arch/x86/traps.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 7f38ddce6b..2d585c8c43 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -72,6 +72,7 @@ #include <asm/mc146818rtc.h> #include <asm/hpet.h> #include <public/arch-x86/cpuid.h> +#include <xsm/xsm.h> /* * opt_nmi: one of 'ignore', 'dom0', or 'fatal'. @@ -1680,6 +1681,21 @@ static int admin_io_okay( return ioports_access_permitted(v->domain, port, port + bytes - 1); } +static int pci_cfg_ok(struct domain *d, int write, int size) +{ + uint32_t machine_bdf; + uint16_t start, end; + if (!IS_PRIV(d)) + return 0; + + machine_bdf = (d->arch.pci_cf8 >> 8) & 0xFFFF; + start = d->arch.pci_cf8 & 0xFF; + end = start + size - 1; + if (xsm_pci_config_permission(d, machine_bdf, start, end, write)) + return 0; + return 1; +} + static uint32_t guest_io_read( unsigned int port, unsigned int bytes, struct vcpu *v, struct cpu_user_regs *regs) @@ -1726,12 +1742,13 @@ static uint32_t guest_io_read( size = 4; sub_data = v->domain->arch.pci_cf8; } - else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) ) + else if ( (port & 0xfffc) == 0xcfc ) { size = min(bytes, 4 - (port & 3)); if ( size == 3 ) size = 2; - sub_data = pci_conf_read(v->domain->arch.pci_cf8, port & 3, size); + if ( pci_cfg_ok(v->domain, 0, size) ) + sub_data = pci_conf_read(v->domain->arch.pci_cf8, port & 3, size); } if ( size == 4 ) @@ -1798,12 +1815,13 @@ static void guest_io_write( size = 4; v->domain->arch.pci_cf8 = data; } - else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) ) + else if ( (port & 0xfffc) == 0xcfc ) { size = min(bytes, 4 - (port & 3)); if ( size == 3 ) size = 2; - pci_conf_write(v->domain->arch.pci_cf8, port & 3, size, data); + if ( pci_cfg_ok(v->domain, 1, size) ) + pci_conf_write(v->domain->arch.pci_cf8, port & 3, size, data); } if ( size == 4 ) |