aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/traps.c
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-12-18 14:34:42 +0000
committerDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-12-18 14:34:42 +0000
commit32103e04bed97da5c42a12d2d40cbdfff61e8cdb (patch)
tree4bf75215cdf821c41f61f0950ba9887f334a19d7 /xen/arch/x86/traps.c
parentf2271ccd4576e36a975a5648cee436b12e1d857a (diff)
downloadxen-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.c26
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 )