From: Alex Williamson <alex.williamson@redhat.com>
To: "Gonglei (Arei)" <arei.gonglei@huawei.com>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"Huangweidong (C)" <weidong.huang@huawei.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"mst@redhat.com" <mst@redhat.com>
Subject: Re: [Qemu-devel] [RFC PATCH]pci-assign: Fix memory out of bound when MSI-X table not fit in a single page
Date: Wed, 02 Apr 2014 09:41:53 -0600 [thread overview]
Message-ID: <1396453313.476.291.camel@ul30vt.home> (raw)
In-Reply-To: <33183CC9F5247A488A2544077AF19020815DCDC3@SZXEMA503-MBS.china.huawei.com>
On Wed, 2014-04-02 at 08:50 +0000, Gonglei (Arei) wrote:
> Hi,
> > > >
> > > Actually I move the judge in function assigned_dev_register_msix_mmio.
> > > Because assigned_dev_register_msix_mmio do not address the return value,
> > > if dev->msix_table is null, this will result a segfault. Right?
> >
> > I see the confusion, there is a bug there but I think it should be fixed
> > by setting msix_table to NULL in the MAP_FAILED case. The intent of
> > assigned_dev_msix_reset() is to put the msix table in the state it would
> > be in at reset. Without a memset() that doesn't happen. I believe the
> > reason we test msix_table in assigned_dev_msix_reset() is so that the
> > function could be called from anywhere, such as reset_assigned_device()
> > even though it's currently not called from there. So, if the memset()
> > gets removed, then the whole function should be dissolved. I'd prefer
> > to keep it and store or recalculate the size for memset.
> >
> Yep, agreed. Thank you so much. I want to post a formal patch, can I?
Of course, bug fixes are always welcome. Features and significant code
churn to pci-assign probably require some discussion as we'd really like
to see it phased out in favor of vfio-pci.
> > > > > memset(dev->msix_table, 0, MSIX_PAGE_SIZE);
> > > >
> > > > This memset may no longer cover the entire table
> > > >
> > > Yeah, this memset is useless. Do it in assigned_dev_register_msix_mmio.
> >
> > Not useless, see above.
> >
> > > > >
> > > > > for (i = 0, entry = dev->msix_table; i < dev->msix_max; i++, entry++)
> > {
> > > > > @@ -1604,13 +1600,31 @@ static void
> > > > assigned_dev_msix_reset(AssignedDevice *dev)
> > > > >
> > > > > static int assigned_dev_register_msix_mmio(AssignedDevice *dev)
> > > > > {
> > > > > - dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE,
> > > > PROT_READ|PROT_WRITE,
> > > > > + int nr_pages;
> > > > > + int size;
> > > > > + int entry_per_page = MSIX_PAGE_SIZE / sizeof(struct
> > MSIXTableEntry);
> > > > > +
> > > > > + if (dev->msix_max > entry_per_page) {
> > > > > + nr_pages = dev->msix_max / entry_per_page;
> > > > > + if (dev->msix_max % entry_per_page) {
> > > > > + nr_pages += 1;
> > > > > + }
> > > > > + } else {
> > > > > + nr_pages = 1;
> > > > > + }
> > > > > +
> > > > > + size = MSIX_PAGE_SIZE * nr_pages;
> > > >
> > > > Agree with the ROUND_UP comments:
> > > >
> > > > size = ROUND_UP(dev->msix_max * sizeof(struct MSIXTableEntry),
> > > > MSIX_PAGE_SIZE);
> > > >
> > > Nice. I don't know the macro before. Thank you so much!
> > > > > + dev->msix_table = mmap(NULL, size, PROT_READ|PROT_WRITE,
> > > > > MAP_ANONYMOUS|MAP_PRIVATE, 0,
> > 0);
> > > > > if (dev->msix_table == MAP_FAILED) {
> > > > > error_report("fail allocate msix_table! %s", strerror(errno));
> > > > > return -EFAULT;
> > > > > }
> > > > > + if (!dev->msix_table) {
> > > > > + return -EFAULT;
> > > > > + }
> > > >
> > > > This is a bogus test for mmap(2)
> > > >
> > > > >
> > > > > + memset(dev->msix_table, 0, size);
> > > >
> > > > This is unnecessary when assigned_dev_msix_reset() is fixed to memset
> > > > the whole mmap.
> > > >
> > > > > assigned_dev_msix_reset(dev);
> > > > >
> > > > > memory_region_init_io(&dev->mmio, OBJECT(dev),
> > > > &assigned_dev_msix_mmio_ops,
> > > >
> > > > This memory_region_init_io also requires a size parameter that isn't
> > > > updated for the new size.
> > > >
> > > Nice catch.
> > > > As noted by other comments, the munmap() size isn't addressed.
> > > >
> > > Get it.
> > > > IMHO, the correct way to fix this would be to update pci-assign to use
> > > > the msix infrastructure, but legacy KVM assignment is being phased out
> > > > and replaced by VFIO. Is there something that ties you to pci-assign
> > > > instead of using vfio-pci? Thanks,
> > > >
> > > I will have a try. Alex, What's your opinion about my former letter about the
> > MSI-X maximum entry.
> >
> > From other thread:
> >
> > > BTW, do you think the KVM should upsize the max support MSI-X entry to
> > 2048.
> > > Because the MSI-X supports a maximum table size of 2048 entries, which is
> > descript in
> > > PCI specification 3.0 version 6.8.3.2: "MSI-X Configuration".
> > >
> > > The history patch about downsize the MSI-X entry size to 256:
> > >
> > http://thread.gmane.org/gmane.comp.emulators.kvm.devel/38852/focus=388
> > 49
> >
> > No, I think we should deprecate KVM device assignment and use VFIO.
> > Thanks,
> >
> OK. I will send the result of using VFIO later.
Great, please let me know if you have any problems. Thanks,
Alex
prev parent reply other threads:[~2014-04-02 15:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-01 15:23 [Qemu-devel] [RFC PATCH]pci-assign: Fix memory out of bound when MSI-X table not fit in a single page Gonglei (Arei)
2014-04-01 15:45 ` Michael S. Tsirkin
2014-04-02 3:12 ` Gonglei (Arei)
2014-04-02 3:45 ` Alex Williamson
2014-04-02 4:18 ` Gonglei (Arei)
2014-04-02 4:47 ` Alex Williamson
2014-04-02 8:50 ` Gonglei (Arei)
2014-04-02 15:41 ` Alex Williamson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1396453313.476.291.camel@ul30vt.home \
--to=alex.williamson@redhat.com \
--cc=arei.gonglei@huawei.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=weidong.huang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).