[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 6/7] vpci/msix: carve p2m hole for MSIX MMIO regions
Make sure the MSIX MMIO regions don't have p2m entries setup, so that accesses to them trap into the hypervisor and can be handled by vpci. This is a side-effect of commit 042678762 for PVH Dom0, which added mappings for all the reserved regions into the Dom0 p2m. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Cc: George Dunlap <George.Dunlap@xxxxxxxxxxxxx> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Julien Grall <julien.grall@xxxxxxx> Cc: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx> Cc: Tim Deegan <tim@xxxxxxx> Cc: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/drivers/vpci/header.c | 8 ++++++++ xen/drivers/vpci/msix.c | 40 +++++++++++++++++++++++++++++++++++++++ xen/include/xen/vpci.h | 3 +++ 3 files changed, 51 insertions(+) diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c index 4af85d3c02..455dd4fc90 100644 --- a/xen/drivers/vpci/header.c +++ b/xen/drivers/vpci/header.c @@ -88,6 +88,14 @@ static void modify_decoding(const struct pci_dev *pdev, bool map, bool rom_only) uint16_t cmd; unsigned int i; + /* + * Make sure there are no mappings in the MSIX MMIO areas, so that accesses + * can be trapped (and emulated) by Xen when the memory decoding bit is + * enabled. + */ + if ( map && !rom_only && vpci_make_msix_hole(pdev) ) + return; + for ( i = 0; i < ARRAY_SIZE(header->bars); i++ ) { if ( !MAPPABLE_BAR(&header->bars[i]) ) diff --git a/xen/drivers/vpci/msix.c b/xen/drivers/vpci/msix.c index 1960dae123..5759551724 100644 --- a/xen/drivers/vpci/msix.c +++ b/xen/drivers/vpci/msix.c @@ -21,6 +21,7 @@ #include <xen/vpci.h> #include <asm/msi.h> +#include <asm/p2m.h> #define VMSIX_SIZE(num) offsetof(struct vpci_msix, entries[num]) @@ -395,6 +396,45 @@ static const struct hvm_mmio_ops vpci_msix_table_ops = { .write = msix_write, }; +int vpci_make_msix_hole(const struct pci_dev *pdev) +{ + struct domain *d = pdev->domain; + unsigned int i; + + if ( !pdev->vpci->msix ) + return 0; + + /* Make sure there's a hole for the MSIX table/PBA in the p2m. */ + for ( i = 0; i < ARRAY_SIZE(pdev->vpci->msix->tables); i++ ) + { + unsigned long start = PFN_DOWN(vmsix_table_addr(pdev->vpci, i)); + unsigned long end = PFN_DOWN(vmsix_table_addr(pdev->vpci, i) + + vmsix_table_size(pdev->vpci, i) - 1); + + for ( ; start <= end; start++ ) + { + p2m_type_t t; + mfn_t mfn = get_gfn_query(d, start, &t); + + if ( t == p2m_mmio_direct && mfn_x(mfn) == start ) + clear_identity_p2m_entry(d, start); + else if ( t != p2m_mmio_dm ) + { + put_gfn(d, start); + gprintk(XENLOG_WARNING, + "%04x:%02x:%02x.%u: existing mapping (mfn: %" PRI_mfn + "type: %d) at %#lx clobbers MSIX MMIO area\n", + pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), mfn_x(mfn), t, start); + return -EEXIST; + } + put_gfn(d, start); + } + } + + return 0; +} + static int init_msix(struct pci_dev *pdev) { struct domain *d = pdev->domain; diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index f97c48a8f1..e0c22ad81c 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -151,6 +151,9 @@ struct vpci_vcpu { #ifdef __XEN__ void vpci_dump_msi(void); +/* Make sure there's a hole in the p2m for the MSIX mmio areas. */ +int vpci_make_msix_hole(const struct pci_dev *pdev); + /* Arch-specific vPCI MSI helpers. */ void vpci_msi_arch_mask(struct vpci_msi *msi, const struct pci_dev *pdev, unsigned int entry, bool mask); -- 2.19.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |