aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/video
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-09-11 16:01:15 +0200
committerJan Beulich <jbeulich@suse.com>2012-09-11 16:01:15 +0200
commite46ea4d44dc0929d9e15dcde5c13b569278970d2 (patch)
tree6992a7be13ec2c6a58fe7c2e7e9d6b5f17bc0e58 /xen/drivers/video
parent510cbdf5edecc3a4898c87b02de9e4f3e9360eda (diff)
downloadxen-e46ea4d44dc0929d9e15dcde5c13b569278970d2.tar.gz
xen-e46ea4d44dc0929d9e15dcde5c13b569278970d2.tar.bz2
xen-e46ea4d44dc0929d9e15dcde5c13b569278970d2.zip
PCI: don't allow guest assignment of devices used by Xen
This covers the devices used for the console and the AMD IOMMU ones (as would be any others that might get passed to pci_ro_device()). Boot video device determination cloned from similar Linux logic. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/drivers/video')
-rw-r--r--xen/drivers/video/vga.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
index 7696946c73..9fabaf4ab4 100644
--- a/xen/drivers/video/vga.c
+++ b/xen/drivers/video/vga.c
@@ -9,6 +9,7 @@
#include <xen/lib.h>
#include <xen/mm.h>
#include <xen/vga.h>
+#include <xen/pci.h>
#include <asm/io.h>
/* Filled in by arch boot code. */
@@ -106,6 +107,61 @@ void __init vga_endboot(void)
if ( !vgacon_keep )
vga_puts = vga_noop_puts;
+ else
+ {
+ int bus, devfn;
+
+ for ( bus = 0; bus < 256; ++bus )
+ for ( devfn = 0; devfn < 256; ++devfn )
+ {
+ const struct pci_dev *pdev;
+ u8 b = bus, df = devfn, sb;
+
+ spin_lock(&pcidevs_lock);
+ pdev = pci_get_pdev(0, bus, devfn);
+ spin_unlock(&pcidevs_lock);
+
+ if ( !pdev ||
+ pci_conf_read16(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
+ PCI_CLASS_DEVICE) != 0x0300 ||
+ !(pci_conf_read16(0, bus, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), PCI_COMMAND) &
+ (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) )
+ continue;
+
+ while ( b )
+ {
+ switch ( find_upstream_bridge(0, &b, &df, &sb) )
+ {
+ case 0:
+ b = 0;
+ break;
+ case 1:
+ switch ( pci_conf_read8(0, b, PCI_SLOT(df),
+ PCI_FUNC(df),
+ PCI_HEADER_TYPE) )
+ {
+ case PCI_HEADER_TYPE_BRIDGE:
+ case PCI_HEADER_TYPE_CARDBUS:
+ if ( pci_conf_read16(0, b, PCI_SLOT(df),
+ PCI_FUNC(df),
+ PCI_BRIDGE_CONTROL) &
+ PCI_BRIDGE_CTL_VGA )
+ continue;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ if ( !b )
+ {
+ printk(XENLOG_INFO "Boot video device %02x:%02x.%u\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ pci_hide_device(bus, devfn);
+ }
+ }
+ }
switch ( vga_console_info.video_type )
{