On Wed, Nov 23, 2016 at 10:40:10AM +0800, Peter Xu wrote: > 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. Ah, I see. OK. > > 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. But cap_handlers only has PCI_CAP_ID_MAX + 1 (21) elements. If you read anything greater than 20 for cap_id, then boom. drew > > 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 -- 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