[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v7 for-next 09/12] vpci/bars: add handlers to map the BARs
Thanks for the review, and sorry for the very late reply. On Fri, Dec 15, 2017 at 04:43:11AM -0700, Jan Beulich wrote: > >>> On 18.10.17 at 13:40, <roger.pau@xxxxxxxxxx> wrote: > > +static void modify_decoding(const struct pci_dev *pdev, bool map, bool rom) > > +{ > > + struct vpci_header *header = &pdev->vpci->header; > > + uint8_t slot = PCI_SLOT(pdev->devfn), func = PCI_FUNC(pdev->devfn); > > + unsigned int i; > > + > > + for ( i = 0; i < ARRAY_SIZE(header->bars); i++ ) > > + { > > + if ( rom && header->bars[i].type == VPCI_BAR_ROM ) > > + { > > + unsigned int rom_pos = (i == 6) ? PCI_ROM_ADDRESS > > + : PCI_ROM_ADDRESS1; > > + uint32_t val = pci_conf_read32(pdev->seg, pdev->bus, slot, > > func, > > + rom_pos); > > + > > + header->bars[i].enabled = header->bars[i].rom_enabled = map; > > + > > + val &= ~PCI_ROM_ADDRESS_ENABLE; > > + val |= map ? PCI_ROM_ADDRESS_ENABLE : 0; > > + pci_conf_write32(pdev->seg, pdev->bus, slot, func, rom_pos, > > val); > > + break; > > + } > > + if ( !rom && (header->bars[i].type != VPCI_BAR_ROM || > > + header->bars[i].rom_enabled) ) > > + header->bars[i].enabled = map; > > + } > > Looking at all of this, it would clearly be more logical for > rom_enabled to be a per-header instead of a per-BAR flag. Hm, I'm not sure just moving the rom_enable would be such a win, we would still need to iterate over the array of BARs in order to find the position of the ROM BAR and thus which register has to be used (PCI_ROM_ADDRESS or PCI_ROM_ADDRESS1). I could solve that but it would mean adding a bool plus an unsigned int field to store the position of the ROM BAR. Since this is not going to change the behavior I would rather leave this for future improvements, likely when SR-IOV is implemented and we have a better picture of what needs to be stored in the 'header' struct. > > + if ( !rom ) > > + { > > + uint16_t cmd = pci_conf_read16(pdev->seg, pdev->bus, slot, > > + func, PCI_COMMAND); > > + > > + cmd &= ~PCI_COMMAND_MEMORY; > > + cmd |= map ? PCI_COMMAND_MEMORY : 0; > > + pci_conf_write16(pdev->seg, pdev->bus, slot, func, PCI_COMMAND, > > + cmd); > > + } > > For both writes, wouldn't it be worthwhile to avoid them when the > flag is already in the intended state? If the flag is in the intended state modify_decoding would not be called at all, because cmd_write and rom_write already filter those cases. > > + if ( v->vpci.map ) > > + { > > + spin_lock(&v->vpci.pdev->vpci->lock); > > + modify_decoding(v->vpci.pdev, v->vpci.map, v->vpci.rom); > > + spin_unlock(&v->vpci.pdev->vpci->lock); > > + } > > + /* fallthrough. */ > > + case -ENOMEM: > > + /* > > + * Other errors are ignored, hopping that at least some regions > > hoping > > I also don't really understand your intentions here: If other errors > are being ignored, wouldn't that lead to the rangeset being leaked? > Or is "other" here meant to include -ENOMEM, in which case you > really mean "default:" above? Yes, s/case 0/default/ above, or else this is simply not true, and leaks the partially consumed rangeset. > > struct vpci { > > /* List of vPCI handlers for a device. */ > > struct list_head handlers; > > spinlock_t lock; > > + > > +#ifdef __XEN__ > > + /* Hide the rest of the vpci struct from the user-space test harness. > > */ > > + struct vpci_header { > > + /* Information about the PCI BARs of this device. */ > > + struct vpci_bar { > > + uint64_t addr; > > + uint64_t size; > > + enum { > > + VPCI_BAR_EMPTY, > > + VPCI_BAR_IO, > > + VPCI_BAR_MEM32, > > + VPCI_BAR_MEM64_LO, > > + VPCI_BAR_MEM64_HI, > > + VPCI_BAR_ROM, > > + } type; > > + bool prefetchable : 1; > > + /* Store whether the BAR is mapped into guest p2m. */ > > + bool enabled : 1; > > + /* > > + * Store whether the ROM enable bit is set (doesn't imply ROM > > BAR > > + * is mapped into guest p2m). Only used for type VPCI_BAR_ROM. > > + */ > > + bool rom_enabled : 1; > > + } bars[7]; /* At most 6 BARS + 1 expansion ROM BAR. */ > > + /* FIXME: currently there's no support for SR-IOV. */ > > + } header; > > +#endif > > }; > > > > +#ifdef __XEN__ > > +struct vpci_vcpu { > > + struct rangeset *mem; > > + const struct pci_dev *pdev; > > + bool map : 1; > > + bool rom : 1; > > +}; > > +#endif > > This structure could do with a comment briefly noting it purpose. > Also - if the #ifdef really needed here? I prefer to add the ifdef rather than adding a struct rangeset forward declaration to tests/vpci/emul.h. I've added the following comment: /* Per-vcpu structure to store state while {un}mapping of PCI BARs. */ Thanks, Roger. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |