[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2] xen/pci: detect when BARs are not suitably positioned
On Thu, Jan 27, 2022 at 09:48:16AM +0100, Jan Beulich wrote: > On 27.01.2022 09:22, Roger Pau Monne wrote: > > --- a/xen/arch/arm/mm.c > > +++ b/xen/arch/arm/mm.c > > @@ -1625,6 +1625,17 @@ bool is_iomem_page(mfn_t mfn) > > return !mfn_valid(mfn); > > } > > > > +bool is_iomem_range(paddr_t start, uint64_t size) > > +{ > > + unsigned int i; > > + > > + for ( i = 0; i < PFN_UP(size); i++ ) > > + if ( !is_iomem_page(_mfn(PFN_DOWN(start) + i)) ) > > + return false; > > + > > + return true; > > +} > > I'm afraid you can't very well call this non-RFC as long as this doesn't > scale. Or if you're building on this still being dead code on Arm, then > some kind of "fixme" annotation would be needed here (or the function be > omitted altogether, for Arm folks to sort out before they actually start > selecting the HAS_PCI Kconfig setting). I was expecting the lack of 'RFC' tag to attract the attention of the maintainers for feedback. If not I'm happy to add a FIXME here or just drop the chunk. > > --- a/xen/arch/x86/mm.c > > +++ b/xen/arch/x86/mm.c > > @@ -783,6 +783,23 @@ bool is_iomem_page(mfn_t mfn) > > return (page_get_owner(page) == dom_io); > > } > > > > +bool is_iomem_range(paddr_t start, uint64_t size) > > +{ > > + unsigned int i; > > + > > + for ( i = 0; i < e820.nr_map; i++ ) > > + { > > + const struct e820entry *entry = &e820.map[i]; > > + > > + /* Do not allow overlaps with any memory range. */ > > + if ( start < entry->addr + entry->size && > > + entry->addr < start + size ) > > + return false; > > + } > > + > > + return true; > > +} > > I should have realized (and pointed out) earlier that with the type > check dropped the function name no longer represents what the > function does. It now really is unsuitable for about anything other > that the checking of BARs. is_devmem_range would be more suitable? I will wrap this in an #ifdef HAS_PCI section now. > > @@ -267,11 +270,75 @@ static void check_pdev(const struct pci_dev *pdev) > > } > > break; > > > > + case PCI_HEADER_TYPE_NORMAL: > > + nbars = PCI_HEADER_NORMAL_NR_BARS; > > + rom_pos = PCI_ROM_ADDRESS; > > + break; > > + > > case PCI_HEADER_TYPE_CARDBUS: > > /* TODO */ > > break; > > } > > #undef PCI_STATUS_CHECK > > + > > + /* Check if BARs overlap with other memory regions. */ > > + val = pci_conf_read16(pdev->sbdf, PCI_COMMAND); > > + if ( !(val & PCI_COMMAND_MEMORY) || pdev->ignore_bars ) > > + return; > > + > > + pci_conf_write16(pdev->sbdf, PCI_COMMAND, val & ~PCI_COMMAND_MEMORY); > > + for ( i = 0; i < nbars; ) > > + { > > + uint64_t addr, size; > > + unsigned int reg = PCI_BASE_ADDRESS_0 + i * 4; > > + int rc = 1; > > + > > + if ( (pci_conf_read32(pdev->sbdf, reg) & PCI_BASE_ADDRESS_SPACE) != > > + PCI_BASE_ADDRESS_SPACE_MEMORY ) > > + goto next; > > + > > + rc = pci_size_mem_bar(pdev->sbdf, reg, &addr, &size, > > + (i == nbars - 1) ? PCI_BAR_LAST : 0); > > + if ( rc < 0 ) > > + /* Unable to size, better leave memory decoding disabled. */ > > + return; > > + if ( size && !is_iomem_range(addr, size) ) > > + { > > + /* > > + * Return without enabling memory decoding if BAR position is > > not > > + * in IO suitable memory. Let the hardware domain re-position > > the > > + * BAR. > > + */ > > + printk(XENLOG_WARNING > > +"%pp disabled: BAR%u [%" PRIx64 ", %" PRIx64 ") overlaps with memory > > map\n", > > I guess despite its length this still wants indenting properly. Maybe > you could fold this and ... > > > + &pdev->sbdf, i, addr, addr + size); > > + return; > > + } > > + > > + next: > > + ASSERT(rc > 0); > > + i += rc; > > + } > > + > > + if ( rom_pos && > > + (pci_conf_read32(pdev->sbdf, rom_pos) & PCI_ROM_ADDRESS_ENABLE) ) > > + { > > + uint64_t addr, size; > > + int rc = pci_size_mem_bar(pdev->sbdf, rom_pos, &addr, &size, > > + PCI_BAR_ROM); > > + > > + if ( rc < 0 ) > > + return; > > + if ( size && !is_iomem_range(addr, size) ) > > + { > > + printk(XENLOG_WARNING > > +"%pp disabled: ROM BAR [%" PRIx64 ", %" PRIx64 ") overlaps with memory > > map\n", > > .. this into > > static const char warn[] = > "%pp disabled: %sBAR [%" PRIx64 ", %" PRIx64 ") overlaps with memory > map\n"; > > to limit indentation and redundancy at the same time? Could then also > be re-used later for the SR-IOV BAR check. Sure. Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |