diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-09-11 16:01:15 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-09-11 16:01:15 +0200 |
commit | e46ea4d44dc0929d9e15dcde5c13b569278970d2 (patch) | |
tree | 6992a7be13ec2c6a58fe7c2e7e9d6b5f17bc0e58 /xen/drivers/video | |
parent | 510cbdf5edecc3a4898c87b02de9e4f3e9360eda (diff) | |
download | xen-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.c | 56 |
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 ) { |