All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
@ 2015-12-01 16:23 Shmulik Ladkani
  2015-12-01 16:36 ` Marcel Apfelbaum
  0 siblings, 1 reply; 9+ messages in thread
From: Shmulik Ladkani @ 2015-12-01 16:23 UTC (permalink / raw)
  To: Michael S. Tsirkin, Marcel Apfelbaum; +Cc: qemu-devel, Shmulik Ladkani

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>
---
 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..cee1b7b 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->saved_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->saved_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..f18e948 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 saved_dc_realize;
     void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp);
 } VirtioPCIClass;
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-01 16:23 [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method Shmulik Ladkani
@ 2015-12-01 16:36 ` Marcel Apfelbaum
  2015-12-01 19:30   ` Shmulik Ladkani
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Apfelbaum @ 2015-12-01 16:36 UTC (permalink / raw)
  To: Shmulik Ladkani, Michael S. Tsirkin; +Cc: qemu-devel

On 12/01/2015 06:23 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>
> ---
>   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..cee1b7b 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;

Hi,

Here you should check only for 'pci_is_express(pci_dev)' .


>
> -        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;

And here you should also check:
      pci_bus_is_express(pci_dev->bus) && !pci_bus_is_root(pci_dev->bus))

The reason is the device becomes express only if *all* the conditions are met.

> +    }
> +
> +    vpciklass->saved_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->saved_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..f18e948 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 saved_dc_realize;

I would change the name to parent_realize :)

Also please add "for-2.5" to prefix.

Thanks for posting it!
Marcel

>       void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp);
>   } VirtioPCIClass;
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-01 16:36 ` Marcel Apfelbaum
@ 2015-12-01 19:30   ` Shmulik Ladkani
  2015-12-01 20:46     ` Marcel Apfelbaum
  0 siblings, 1 reply; 9+ messages in thread
From: Shmulik Ladkani @ 2015-12-01 19:30 UTC (permalink / raw)
  To: Marcel Apfelbaum; +Cc: qemu-devel, Michael S. Tsirkin

Hi,

On Tue, 1 Dec 2015 18:36:39 +0200 Marcel Apfelbaum <marcel@redhat.com> wrote:
> > +    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus) &&
> > +        !pci_bus_is_root(pci_dev->bus)) {
> >           int pos;
> 
> Here you should check only for 'pci_is_express(pci_dev)' .

[snip]

> > +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;
> 
> And here you should also check:
>       pci_bus_is_express(pci_dev->bus) && !pci_bus_is_root(pci_dev->bus))
> 
> The reason is the device becomes express only if *all* the conditions
> are met.

I'm ok with either approaches.

However it seems common practice to set QEMU_PCI_CAP_EXPRESS
unconditionally for PCIE devices.

The few existing PCIE devices do so by assigning their
PCIDeviceClass.is_express to 1 within their 'class_init', regardless the
properties of the bus their on.
(e.g. xhci_class_init, megasas_class_init, vfio_pci_dev_class_init,
 nvme_class_init, and more)

Some devices later call pcie_endpoint_cap_init conditionally.
(e.g. usb_xhci_realize).

Can you please examine this and let me know the preferred approach?

> > +    DeviceRealize saved_dc_realize;
> 
> I would change the name to parent_realize :)

Sure.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-01 19:30   ` Shmulik Ladkani
@ 2015-12-01 20:46     ` Marcel Apfelbaum
  2015-12-02  8:01       ` Shmulik Ladkani
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Apfelbaum @ 2015-12-01 20:46 UTC (permalink / raw)
  To: Shmulik Ladkani; +Cc: qemu-devel, Michael S. Tsirkin

On 12/01/2015 09:30 PM, Shmulik Ladkani wrote:
> Hi,
>
> On Tue, 1 Dec 2015 18:36:39 +0200 Marcel Apfelbaum <marcel@redhat.com> wrote:
>>> +    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus) &&
>>> +        !pci_bus_is_root(pci_dev->bus)) {
>>>            int pos;
>>
>> Here you should check only for 'pci_is_express(pci_dev)' .
>
> [snip]
>
>>> +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;
>>
>> And here you should also check:
>>        pci_bus_is_express(pci_dev->bus) && !pci_bus_is_root(pci_dev->bus))
>>
>> The reason is the device becomes express only if *all* the conditions
>> are met.
>
> I'm ok with either approaches.
>
> However it seems common practice to set QEMU_PCI_CAP_EXPRESS
> unconditionally for PCIE devices.
>
> The few existing PCIE devices do so by assigning their
> PCIDeviceClass.is_express to 1 within their 'class_init', regardless the
> properties of the bus their on.
> (e.g. xhci_class_init, megasas_class_init, vfio_pci_dev_class_init,
>   nvme_class_init, and more)
>
> Some devices later call pcie_endpoint_cap_init conditionally.
> (e.g. usb_xhci_realize).
>
> Can you please examine this and let me know the preferred approach?

Yes, I saw that..., as always not a walk in the park.

- So we have "is_express = true" <=> QEMU_PCI_CAP_EXPRESS on <=> "config size = PCIe"
- Not related to the above (!!), if (some condition) => add PCIe express capability
   (megasas is the exception)

Let's take "usb_xhci":
  - If we put it under a PCI bus it will not be an express device, but
    it will have a "big" config space. Also pci_is_express(dev) will still return true!
  - This is probably a bug. (or I am missing something)
NVME:
  - simple, always PCIe
Now let's see vfio-pci:
  - is_express = true (with the comment: we might be) => PCIe config
  - vfio_populate_device => checks actual register (I think),
    if not PCIe, rewinds it :
	vdev->config_size = reg_info.size;
     	if (vdev->config_size == PCI_CONFIG_SPACE_SIZE) {
         	vdev->pdev.cap_present &= ~QEMU_PCI_CAP_EXPRESS;
     	}
  - better (we still "loose" the space, but at least pci_is_express will return false)

Now virtio case:
  - If we split the conditions into 2 parts we would have usb_xhci issues:
    - PCIe config space for a PCI device if *some* conditions are not met.
    - pci_is_express will return true when we don't want that.
If you see a reason to split, please do, I only see problems :)

Our solution to make it "clean" is to not mark the class as "is_express",
but hijack realize method and add our "conditions" before calling it.

A more elegant solution would be to make is_express a method and let the subclasses
implement it:
  - vfio will look for the actual device config space
  - NVME will return true
  - usb_xhci will condition this on the bus type
  - virtio will have its own conditions.
But this is not 2.5 material.

I hope I helped,
Thanks for getting involved.
Marcel

>
>>> +    DeviceRealize saved_dc_realize;
>>
>> I would change the name to parent_realize :)
>
> Sure.
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-01 20:46     ` Marcel Apfelbaum
@ 2015-12-02  8:01       ` Shmulik Ladkani
  2015-12-02  9:51         ` Marcel Apfelbaum
  0 siblings, 1 reply; 9+ messages in thread
From: Shmulik Ladkani @ 2015-12-02  8:01 UTC (permalink / raw)
  To: Marcel Apfelbaum; +Cc: qemu-devel, Michael S. Tsirkin

Thanks Marcel,

On Tue, 1 Dec 2015 22:46:33 +0200, marcel@redhat.com wrote:
> >> The reason is the device becomes express only if *all* the conditions
> >> are met.
> >
> > I'm ok with either approaches.
> >
> > However it seems common practice to set QEMU_PCI_CAP_EXPRESS
> > unconditionally for PCIE devices.
> >
> > The few existing PCIE devices do so by assigning their
> > PCIDeviceClass.is_express to 1 within their 'class_init', regardless the
> > properties of the bus their on.
> > (e.g. xhci_class_init, megasas_class_init, vfio_pci_dev_class_init,
> >   nvme_class_init, and more)
> >
> > Some devices later call pcie_endpoint_cap_init conditionally.
> > (e.g. usb_xhci_realize).
> >
> > Can you please examine this and let me know the preferred approach?
> 
> Yes, I saw that..., as always not a walk in the park.
> 
> - So we have "is_express = true" <=> QEMU_PCI_CAP_EXPRESS on <=> "config size = PCIe"
> - Not related to the above (!!), if (some condition) => add PCIe express capability
>    (megasas is the exception)
> 
> Let's take "usb_xhci":
>   - If we put it under a PCI bus it will not be an express device, but
>     it will have a "big" config space. Also pci_is_express(dev) will still return true!
>   - This is probably a bug. (or I am missing something)

I actually assumed this is the right behavior.

A device class reports whether its instances *could* be pcie by arming
its PCIDeviceClass.is_express.
As such, the "big" config space is allocated for the instance. This is
harmless.

Such a device may (or may not) be connected to a pcie bus, and only if
so, we report it is a pcie endpoint.

Also, pcie_add_capability is allowed on that device, in order to setup
whatever capabilities on its pcie config space (even if finally not on a
pcie bus).

Moreover, VMSTATE_PCIE_DEVICE (which uses vmstate_pcie_device rather
than vmstate_pci_device) can be used for that device's
VMStateDescription fields *without* worrying whether the actual config
space is "big" or "small".
Otherwise one should examine whether vmstate_pcie_device or
vmstate_pci_device need to be used. Seems tedious.

This is the reasoning I can think of, why assigning QEMU_PCI_CAP_EXPRESS
and reporting pcie_endpoint_cap_init are not tightly coupled.

Indeed, no strict solution here, both approaches seem reasoanble (and
both are used!).

WDYT? Is my above interpretation makes sense?

Regards,
Shmulik

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-02  8:01       ` Shmulik Ladkani
@ 2015-12-02  9:51         ` Marcel Apfelbaum
  2015-12-02 13:30           ` Shmulik Ladkani
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Apfelbaum @ 2015-12-02  9:51 UTC (permalink / raw)
  To: Shmulik Ladkani; +Cc: qemu-devel, Michael S. Tsirkin

On 12/02/2015 10:01 AM, Shmulik Ladkani wrote:
> Thanks Marcel,
>
> On Tue, 1 Dec 2015 22:46:33 +0200, marcel@redhat.com wrote:
>>>> The reason is the device becomes express only if *all* the conditions
>>>> are met.
>>>
>>> I'm ok with either approaches.
>>>
>>> However it seems common practice to set QEMU_PCI_CAP_EXPRESS
>>> unconditionally for PCIE devices.
>>>
>>> The few existing PCIE devices do so by assigning their
>>> PCIDeviceClass.is_express to 1 within their 'class_init', regardless the
>>> properties of the bus their on.
>>> (e.g. xhci_class_init, megasas_class_init, vfio_pci_dev_class_init,
>>>    nvme_class_init, and more)
>>>
>>> Some devices later call pcie_endpoint_cap_init conditionally.
>>> (e.g. usb_xhci_realize).
>>>
>>> Can you please examine this and let me know the preferred approach?
>>
>> Yes, I saw that..., as always not a walk in the park.
>>
>> - So we have "is_express = true" <=> QEMU_PCI_CAP_EXPRESS on <=> "config size = PCIe"
>> - Not related to the above (!!), if (some condition) => add PCIe express capability
>>     (megasas is the exception)
>>
>> Let's take "usb_xhci":
>>    - If we put it under a PCI bus it will not be an express device, but
>>      it will have a "big" config space. Also pci_is_express(dev) will still return true!
>>    - This is probably a bug. (or I am missing something)
>
> I actually assumed this is the right behavior.
>
> A device class reports whether its instances *could* be pcie by arming
> its PCIDeviceClass.is_express.
> As such, the "big" config space is allocated for the instance. This is
> harmless.
>
> Such a device may (or may not) be connected to a pcie bus, and only if
> so, we report it is a pcie endpoint.
>
> Also, pcie_add_capability is allowed on that device, in order to setup
> whatever capabilities on its pcie config space (even if finally not on a
> pcie bus).
>
> Moreover, VMSTATE_PCIE_DEVICE (which uses vmstate_pcie_device rather
> than vmstate_pci_device) can be used for that device's
> VMStateDescription fields *without* worrying whether the actual config
> space is "big" or "small".
> Otherwise one should examine whether vmstate_pcie_device or
> vmstate_pci_device need to be used. Seems tedious.
>
> This is the reasoning I can think of, why assigning QEMU_PCI_CAP_EXPRESS
> and reporting pcie_endpoint_cap_init are not tightly coupled.

I agree it may be the reason, but that does not make it right.
I still see two *possible* problems:
1. Pci config space is guest visible. The guest can read/write to
    a place it shouldn't. I don't know if is a *real* issue, but it needs checking.
2. We still have pci_is_express returning true, this is error prone because one
    can use this function assuming the device is express. Maybe we should call it "can_be_express" ?
If the migration construct (VMSTATE) is *the only* reason for doing this, maybe is not a good
enough reason (I am not the one to decide :)  ). Is still it seems a little off to me.

If you think this is good enough, you can simply do the same:
   - Instead of replacing the realize method, just advertise it with "is_express" (meaning it can be express)
   - Leave all the conditions as they were in prev patch.
As a result, the pci config space will have the right length.
The consequences are obvious now, if virtio/pci maintainers are OK with that, so am I.

Thanks,
Marcel




>
> Indeed, no strict solution here, both approaches seem reasoanble (and
> both are used!).
>
> WDYT? Is my above interpretation makes sense?
>
> Regards,
> Shmulik
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-02  9:51         ` Marcel Apfelbaum
@ 2015-12-02 13:30           ` Shmulik Ladkani
  2015-12-02 14:00             ` Marcel Apfelbaum
  0 siblings, 1 reply; 9+ messages in thread
From: Shmulik Ladkani @ 2015-12-02 13:30 UTC (permalink / raw)
  To: Marcel Apfelbaum; +Cc: qemu-devel, Michael S. Tsirkin

Hi,

On Wed, 2 Dec 2015 11:51:46 +0200, marcel@redhat.com wrote:
> 2. We still have pci_is_express returning true, this is error prone because
> one can use this function assuming the device is express. Maybe we should
> call it "can_be_express" ?
> 
> If you think this is good enough, you can simply do the same:
>    - Instead of replacing the realize method, just advertise it with
>      "is_express" (meaning it can be express)
>    - Leave all the conditions as they were in prev patch.
> As a result, the pci config space will have the right length.

Oh but we can't do so, as the change of config space size is guest
visible and breaks migration; it must depend on your x-pcie-disable
flag :)

As I can't decide what's better, I'm following your initial suggestion
and submit for maintainers to review.

However, do note that there are few more evidence that 'pci_is_express'
is true while not necessarily placed on a pcie bus:
- pcie_endpoint_cap_init:
  it tests for 'pci_bus_is_express' although 'dev' is guaranteed to be
  'pci_is_express' (assertion in pcie_cap_init)
- 058fdcf 'xhci: add endpoint cap on express bus only'

Thanks,
Shmulik

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-02 13:30           ` Shmulik Ladkani
@ 2015-12-02 14:00             ` Marcel Apfelbaum
  2015-12-02 14:27               ` Shmulik Ladkani
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Apfelbaum @ 2015-12-02 14:00 UTC (permalink / raw)
  To: Shmulik Ladkani; +Cc: qemu-devel, Michael S. Tsirkin

On 12/02/2015 03:30 PM, Shmulik Ladkani wrote:
> Hi,
>
> On Wed, 2 Dec 2015 11:51:46 +0200, marcel@redhat.com wrote:
>> 2. We still have pci_is_express returning true, this is error prone because
>> one can use this function assuming the device is express. Maybe we should
>> call it "can_be_express" ?
>>
>> If you think this is good enough, you can simply do the same:
>>     - Instead of replacing the realize method, just advertise it with
>>       "is_express" (meaning it can be express)
>>     - Leave all the conditions as they were in prev patch.
>> As a result, the pci config space will have the right length.
>
> Oh but we can't do so, as the change of config space size is guest
> visible and breaks migration; it must depend on your x-pcie-disable
> flag :)

Indeed, we need at least to condition it on  x-pcie-disable.

>
> As I can't decide what's better, I'm following your initial suggestion
> and submit for maintainers to review.

Sure, and thanks for the patience to get to the bottom of it.

>
> However, do note that there are few more evidence that 'pci_is_express'
> is true while not necessarily placed on a pcie bus:

and this is scary ... we really should call it "pci_can_be_express"

> - pcie_endpoint_cap_init:
>    it tests for 'pci_bus_is_express' although 'dev' is guaranteed to be
>    'pci_is_express' (assertion in pcie_cap_init)
> - 058fdcf 'xhci: add endpoint cap on express bus only'


Thanks,
Marcel

>
> Thanks,
> Shmulik
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method
  2015-12-02 14:00             ` Marcel Apfelbaum
@ 2015-12-02 14:27               ` Shmulik Ladkani
  0 siblings, 0 replies; 9+ messages in thread
From: Shmulik Ladkani @ 2015-12-02 14:27 UTC (permalink / raw)
  To: Marcel Apfelbaum; +Cc: qemu-devel, Michael S. Tsirkin

Hi,

On Wed, 2 Dec 2015 16:00:41 +0200, marcel@redhat.com wrote:
> > As I can't decide what's better, I'm following your initial suggestion
> > and submit for maintainers to review.
> 
> Sure, and thanks for the patience to get to the bottom of it.

Sorry, your initial suggestion testing 'pci_bus_is_express() &&
!pci_bus_is_root()' within 'virtio_pci_dc_realize' will not do the job
as in that place pci_dev->bus is still NULL...
It's only assigned at pci_qdev_realize.

I think this is the main reason for separation.

The classes themselves describe the type of the device, which is either
pci or pcie, using k->is_express.

The class code can't tell whether the actual device instance gets
attached to a pci or pcie bus.

So yes, 'pci_is_express' really states whether device instance *can* be
an pcie device.

Thus, I'm going with my initial suggestion, plus minor naming changes.

Many thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-12-02 14:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-01 16:23 [Qemu-devel] [PATCH] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method Shmulik Ladkani
2015-12-01 16:36 ` Marcel Apfelbaum
2015-12-01 19:30   ` Shmulik Ladkani
2015-12-01 20:46     ` Marcel Apfelbaum
2015-12-02  8:01       ` Shmulik Ladkani
2015-12-02  9:51         ` Marcel Apfelbaum
2015-12-02 13:30           ` Shmulik Ladkani
2015-12-02 14:00             ` Marcel Apfelbaum
2015-12-02 14:27               ` Shmulik Ladkani

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.