qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Marcel Apfelbaum <marcel@redhat.com>
To: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>,
	"Michael S. Tsirkin" <mst@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 for-2.5] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
Date: Wed, 2 Dec 2015 17:11:28 +0200	[thread overview]
Message-ID: <565F0A20.8050507@redhat.com> (raw)
In-Reply-To: <1449066801-3002-1-git-send-email-shmulik.ladkani@ravellosystems.com>

On 12/02/2015 04:33 PM, Shmulik Ladkani wrote:
> In 1811e64 'hw/virtio: Add PCIe capability to virtio devices', the
> QEMU_PCI_CAP_EXPRESS capability was added to virtio's pci_dev, within
> 'virtio_pci_realize' - the pci device object realization method.
>
> This occurs to late, as 'pci_qdev_realize' (DeviceClass.realize of
> TYPE_PCI_DEVICE) has already been called, without knowing that the
> device instance is indeed an "express" instance, thus allocating
> insufficient pci config space.
>
> As a result, device may crash upon attempt to write to the PCIE config
> space.
>
> Fix, by arming the QEMU_PCI_CAP_EXPRESS capability early in virtio-pci's
> own DeviceClass realize method.
>
> This also makes code cleaner, as 'virtio_pci_realize' may now access the
> 'pci_is_express' predicate when needed.
>
> Signed-off-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
> ---
>
> Since v1: naming change, as suggested by Marcel Apfelbaum
>
>   hw/virtio/virtio-pci.c | 24 +++++++++++++++++++-----
>   hw/virtio/virtio-pci.h |  1 +
>   2 files changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index dd48562..67f4003 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1814,13 +1814,10 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
>
>       address_space_init(&proxy->modern_as, &proxy->modern_cfg, "virtio-pci-cfg-as");
>
> -    if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE)
> -        && !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN)
> -        && pci_bus_is_express(pci_dev->bus)
> -        && !pci_bus_is_root(pci_dev->bus)) {
> +    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus) &&
> +        !pci_bus_is_root(pci_dev->bus)) {
>           int pos;
>
> -        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
>           pos = pcie_endpoint_cap_init(pci_dev, 0);
>           assert(pos > 0);
>
> @@ -1879,10 +1876,25 @@ static Property virtio_pci_properties[] = {
>       DEFINE_PROP_END_OF_LIST(),
>   };
>
> +static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp)
> +{
> +    VirtioPCIClass *vpciklass = VIRTIO_PCI_GET_CLASS(qdev);
> +    VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
> +    PCIDevice *pci_dev = &proxy->pci_dev;
> +
> +    if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) &&
> +        !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN)) {
> +        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
> +    }
> +
> +    vpciklass->parent_dc_realize(qdev, errp);
> +}
> +
>   static void virtio_pci_class_init(ObjectClass *klass, void *data)
>   {
>       DeviceClass *dc = DEVICE_CLASS(klass);
>       PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +    VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);
>
>       dc->props = virtio_pci_properties;
>       k->realize = virtio_pci_realize;
> @@ -1890,6 +1902,8 @@ static void virtio_pci_class_init(ObjectClass *klass, void *data)
>       k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
>       k->revision = VIRTIO_PCI_ABI_VERSION;
>       k->class_id = PCI_CLASS_OTHERS;
> +    vpciklass->parent_dc_realize = dc->realize;
> +    dc->realize = virtio_pci_dc_realize;
>       dc->reset = virtio_pci_reset;
>   }
>
> diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
> index ffb74bb..a104ff2 100644
> --- a/hw/virtio/virtio-pci.h
> +++ b/hw/virtio/virtio-pci.h
> @@ -105,6 +105,7 @@ typedef struct {
>
>   typedef struct VirtioPCIClass {
>       PCIDeviceClass parent_class;
> +    DeviceRealize parent_dc_realize;
>       void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp);
>   } VirtioPCIClass;
>
>

Hi Michael,

The only thing I want to mention here, (see earlier discussion: https://www.mail-archive.com/qemu-devel@nongnu.org/msg338963.html)
is that in some cases the PCI config space will have PCIe length, even if the device is not express.

To be more precise, the only interesting scenario is when we plug a virtio device directly into
the root complex, in this case we'll have a PCI device with a PCIe config space.

However this happens for other devices as well, it looks like a common practice.

Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>

Thanks,
Marcel

  reply	other threads:[~2015-12-02 15:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-02 14:33 [Qemu-devel] [PATCH v2 for-2.5] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method Shmulik Ladkani
2015-12-02 15:11 ` Marcel Apfelbaum [this message]
2015-12-02 16:49   ` Michael S. Tsirkin
2015-12-02 17:12     ` Shmulik Ladkani
2015-12-02 17:19       ` Michael S. Tsirkin
2015-12-02 17:21         ` Marcel Apfelbaum
2015-12-02 17:22           ` Michael S. Tsirkin
2015-12-02 17:50           ` Shmulik Ladkani
2015-12-02 17:09 ` Michael S. Tsirkin

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=565F0A20.8050507@redhat.com \
    --to=marcel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=shmulik.ladkani@ravellosystems.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).