On Tue, Nov 22, 2016 at 01:30:41PM +0100, Andrew Jones wrote: > On Tue, Nov 22, 2016 at 03:21:37PM +0800, Peter Xu wrote: > > On Tue, Nov 22, 2016 at 08:03:06AM +0100, Alexander Gordeev wrote: > > > On Tue, Nov 22, 2016 at 12:59:20PM +0800, Peter Xu wrote: > > > > On Mon, Nov 21, 2016 at 08:27:52PM +0100, Alexander Gordeev wrote: > > > > > > > > [...] > > > > > > > > > > +void pci_cap_walk(struct pci_dev *dev) > > > > > > +{ > > > > > > + uint8_t cap_offset; > > > > > > + uint8_t cap_id; > > > > > > + > > > > > > + cap_offset = pci_config_readb(dev->bdf, PCI_CAPABILITY_LIST); > > > > > > + while (cap_offset) { > > > > > > + cap_id = pci_config_readb(dev->bdf, cap_offset); > > > > > > + printf("PCI detected cap 0x%x\n", cap_id); > > > > > > + if (cap_handlers[cap_id]) > > > > > > + cap_handlers[cap_id](dev, cap_offset); > > > > > > + cap_offset = pci_config_readb(dev->bdf, cap_offset + 1); > > > > > > + } > > > > > > +} > > > > > > > > > > Are you sure the function above is safe without range (sanity) checks? > > > > > > > > No. :) But if something goes wrong, I guess that's possibly a QEMU PCI > > > > bug. I can add some check if you think is necessary, like, make sure > > > > the loop goes no more than a specific value? > > > > > > Yes - I suppose PCI cap. list has a limit. > > > > Will do. 0xff should suffice. Thanks, > > Well, cap_offset has to be 0xff or smaller, since it comes from readb, > which returns uint8_t. So there's no need to check cap_offset. As for > dereferencing cap_handlers with cap_id, which is what I think Alex > was asking about, then after its read we should simply add > > assert(cap_id <= PCI_CAP_ID_MAX); > > Thanks, > drew IIUC here we need to count the loop in case we have a loop in the cap list (which is possibly QEMU bug, but hardly happen, like cap A points to cap B, while cap B points back to cap A). In that case, I'll do this in the loop: assert(++count <= 255); To make sure the loop ends somewhere. IMHO we don't need to check cap_id since cap_id is only used in: if (cap_handlers[cap_id]) cap_handlers[cap_id](dev, cap_offset); As long as we provide correct handlers, we'll naturally skip all unknown cap_ids. Thanks, -- peterx -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html