diff mbox

[RFC,2/2] xen:i386:pc_piix: create isa bridge specific to IGD passthrough

Message ID 1415172179-7965-2-git-send-email-tiejun.chen@intel.com
State New
Headers show

Commit Message

Tiejun Chen Nov. 5, 2014, 7:22 a.m. UTC
Currently IGD drivers always need to access PCH by 1f.0, and
PCH vendor/device id is used to identify the card.

Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
---
 hw/i386/pc_piix.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

Comments

Michael S. Tsirkin Nov. 5, 2014, 2:09 p.m. UTC | #1
On Wed, Nov 05, 2014 at 03:22:59PM +0800, Tiejun Chen wrote:
> Currently IGD drivers always need to access PCH by 1f.0, and
> PCH vendor/device id is used to identify the card.
> 
> Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
> ---
>  hw/i386/pc_piix.c | 28 +++++++++++++++++++++++++++-
>  1 file changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index b559181..b19c7a9 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -50,7 +50,7 @@
>  #include "cpu.h"
>  #include "qemu/error-report.h"
>  #ifdef CONFIG_XEN
> -#  include <xen/hvm/hvm_info_table.h>
> +#include <xen/hvm/hvm_info_table.h>
>  #endif
>  
>  #define MAX_IDE_BUS 2
> @@ -452,6 +452,31 @@ static void pc_init_isa(MachineState *machine)
>  }
>  
>  #ifdef CONFIG_XEN
> +static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus)
> +{
> +    struct PCIDevice *dev;
> +    Error *local_err = NULL;
> +    uint16_t device_id = 0xffff;
> +
> +    /* Currently IGD drivers always need to access PCH by 1f.0. */
> +    dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
> +                            "xen-igd-passthrough-isa-bridge");
> +
> +    /* Identify PCH card with its own real vendor/device ids.
> +     * Here that vendor id is always PCI_VENDOR_ID_INTEL.
> +     */
> +    if (dev) {
> +        device_id = object_property_get_int(OBJECT(dev), "device-id",
> +                                            &local_err);
> +        if (!local_err && device_id != 0xffff) {
> +            pci_config_set_device_id(dev->config, device_id);
> +            return;
> +        }
> +    }
> +
> +    fprintf(stderr, "xen set xen-igd-passthrough-isa-bridge failed\n");
> +}
> +
>  static void pc_xen_hvm_init(MachineState *machine)
>  {
>      PCIBus *bus;
> @@ -461,6 +486,7 @@ static void pc_xen_hvm_init(MachineState *machine)
>      bus = pci_find_primary_bus();
>      if (bus != NULL) {
>          pci_create_simple(bus, -1, "xen-platform");
> +        xen_igd_passthrough_isa_bridge_create(bus);
>      }
>  }
>  #endif

Can't we defer this step until the GPU is added?
This way there won't be need to poke at host device
directly, you could get all info from dev->config
of the host device.
Additionally the correct bridge would be initialized automatically.


> -- 
> 1.9.1
Tiejun Chen Nov. 17, 2014, 2:47 a.m. UTC | #2
On 2014/11/5 22:09, Michael S. Tsirkin wrote:
> On Wed, Nov 05, 2014 at 03:22:59PM +0800, Tiejun Chen wrote:
>> Currently IGD drivers always need to access PCH by 1f.0, and
>> PCH vendor/device id is used to identify the card.
>>
>> Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
>> ---
>>   hw/i386/pc_piix.c | 28 +++++++++++++++++++++++++++-
>>   1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
>> index b559181..b19c7a9 100644
>> --- a/hw/i386/pc_piix.c
>> +++ b/hw/i386/pc_piix.c
>> @@ -50,7 +50,7 @@
>>   #include "cpu.h"
>>   #include "qemu/error-report.h"
>>   #ifdef CONFIG_XEN
>> -#  include <xen/hvm/hvm_info_table.h>
>> +#include <xen/hvm/hvm_info_table.h>
>>   #endif
>>
>>   #define MAX_IDE_BUS 2
>> @@ -452,6 +452,31 @@ static void pc_init_isa(MachineState *machine)
>>   }
>>
>>   #ifdef CONFIG_XEN
>> +static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus)
>> +{
>> +    struct PCIDevice *dev;
>> +    Error *local_err = NULL;
>> +    uint16_t device_id = 0xffff;
>> +
>> +    /* Currently IGD drivers always need to access PCH by 1f.0. */
>> +    dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
>> +                            "xen-igd-passthrough-isa-bridge");
>> +
>> +    /* Identify PCH card with its own real vendor/device ids.
>> +     * Here that vendor id is always PCI_VENDOR_ID_INTEL.
>> +     */
>> +    if (dev) {
>> +        device_id = object_property_get_int(OBJECT(dev), "device-id",
>> +                                            &local_err);
>> +        if (!local_err && device_id != 0xffff) {
>> +            pci_config_set_device_id(dev->config, device_id);
>> +            return;
>> +        }
>> +    }
>> +
>> +    fprintf(stderr, "xen set xen-igd-passthrough-isa-bridge failed\n");
>> +}
>> +
>>   static void pc_xen_hvm_init(MachineState *machine)
>>   {
>>       PCIBus *bus;
>> @@ -461,6 +486,7 @@ static void pc_xen_hvm_init(MachineState *machine)
>>       bus = pci_find_primary_bus();
>>       if (bus != NULL) {
>>           pci_create_simple(bus, -1, "xen-platform");
>> +        xen_igd_passthrough_isa_bridge_create(bus);
>>       }
>>   }
>>   #endif
>
> Can't we defer this step until the GPU is added?

Sounds great but I can't figure out where we can to do this exactly.

> This way there won't be need to poke at host device
> directly, you could get all info from dev->config
> of the host device.

As I understand We have two steps here:

#1 At first I have to write something to check if we're registering 
00:02.0 & IGD, right? But where? While registering each pci device?

#2 Then if that condition is matched, we register this ISA bridge on its 
associated bus.

Thanks
Tiejun

> Additionally the correct bridge would be initialized automatically.
>
>
>> --
>> 1.9.1
>
Michael S. Tsirkin Nov. 17, 2014, 6:10 a.m. UTC | #3
On Mon, Nov 17, 2014 at 10:47:56AM +0800, Chen, Tiejun wrote:
> On 2014/11/5 22:09, Michael S. Tsirkin wrote:
> >On Wed, Nov 05, 2014 at 03:22:59PM +0800, Tiejun Chen wrote:
> >>Currently IGD drivers always need to access PCH by 1f.0, and
> >>PCH vendor/device id is used to identify the card.
> >>
> >>Signed-off-by: Tiejun Chen <tiejun.chen@intel.com>
> >>---
> >>  hw/i386/pc_piix.c | 28 +++++++++++++++++++++++++++-
> >>  1 file changed, 27 insertions(+), 1 deletion(-)
> >>
> >>diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> >>index b559181..b19c7a9 100644
> >>--- a/hw/i386/pc_piix.c
> >>+++ b/hw/i386/pc_piix.c
> >>@@ -50,7 +50,7 @@
> >>  #include "cpu.h"
> >>  #include "qemu/error-report.h"
> >>  #ifdef CONFIG_XEN
> >>-#  include <xen/hvm/hvm_info_table.h>
> >>+#include <xen/hvm/hvm_info_table.h>
> >>  #endif
> >>
> >>  #define MAX_IDE_BUS 2
> >>@@ -452,6 +452,31 @@ static void pc_init_isa(MachineState *machine)
> >>  }
> >>
> >>  #ifdef CONFIG_XEN
> >>+static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus)
> >>+{
> >>+    struct PCIDevice *dev;
> >>+    Error *local_err = NULL;
> >>+    uint16_t device_id = 0xffff;
> >>+
> >>+    /* Currently IGD drivers always need to access PCH by 1f.0. */
> >>+    dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
> >>+                            "xen-igd-passthrough-isa-bridge");
> >>+
> >>+    /* Identify PCH card with its own real vendor/device ids.
> >>+     * Here that vendor id is always PCI_VENDOR_ID_INTEL.
> >>+     */
> >>+    if (dev) {
> >>+        device_id = object_property_get_int(OBJECT(dev), "device-id",
> >>+                                            &local_err);
> >>+        if (!local_err && device_id != 0xffff) {
> >>+            pci_config_set_device_id(dev->config, device_id);
> >>+            return;
> >>+        }
> >>+    }
> >>+
> >>+    fprintf(stderr, "xen set xen-igd-passthrough-isa-bridge failed\n");
> >>+}
> >>+
> >>  static void pc_xen_hvm_init(MachineState *machine)
> >>  {
> >>      PCIBus *bus;
> >>@@ -461,6 +486,7 @@ static void pc_xen_hvm_init(MachineState *machine)
> >>      bus = pci_find_primary_bus();
> >>      if (bus != NULL) {
> >>          pci_create_simple(bus, -1, "xen-platform");
> >>+        xen_igd_passthrough_isa_bridge_create(bus);
> >>      }
> >>  }
> >>  #endif
> >
> >Can't we defer this step until the GPU is added?
> 
> Sounds great but I can't figure out where we can to do this exactly.
> 
> >This way there won't be need to poke at host device
> >directly, you could get all info from dev->config
> >of the host device.
> 
> As I understand We have two steps here:
> 
> #1 At first I have to write something to check if we're registering 00:02.0
> & IGD, right? But where? While registering each pci device?

In xen_pt_initfn.
Just check the device and vendor ID against the table you have.


> #2 Then if that condition is matched, we register this ISA bridge on its
> associated bus.
> 
> Thanks
> Tiejun

Yep.

> >Additionally the correct bridge would be initialized automatically.
> >
> >
> >>--
> >>1.9.1
> >
diff mbox

Patch

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index b559181..b19c7a9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -50,7 +50,7 @@ 
 #include "cpu.h"
 #include "qemu/error-report.h"
 #ifdef CONFIG_XEN
-#  include <xen/hvm/hvm_info_table.h>
+#include <xen/hvm/hvm_info_table.h>
 #endif
 
 #define MAX_IDE_BUS 2
@@ -452,6 +452,31 @@  static void pc_init_isa(MachineState *machine)
 }
 
 #ifdef CONFIG_XEN
+static void xen_igd_passthrough_isa_bridge_create(PCIBus *bus)
+{
+    struct PCIDevice *dev;
+    Error *local_err = NULL;
+    uint16_t device_id = 0xffff;
+
+    /* Currently IGD drivers always need to access PCH by 1f.0. */
+    dev = pci_create_simple(bus, PCI_DEVFN(0x1f, 0),
+                            "xen-igd-passthrough-isa-bridge");
+
+    /* Identify PCH card with its own real vendor/device ids.
+     * Here that vendor id is always PCI_VENDOR_ID_INTEL.
+     */
+    if (dev) {
+        device_id = object_property_get_int(OBJECT(dev), "device-id",
+                                            &local_err);
+        if (!local_err && device_id != 0xffff) {
+            pci_config_set_device_id(dev->config, device_id);
+            return;
+        }
+    }
+
+    fprintf(stderr, "xen set xen-igd-passthrough-isa-bridge failed\n");
+}
+
 static void pc_xen_hvm_init(MachineState *machine)
 {
     PCIBus *bus;
@@ -461,6 +486,7 @@  static void pc_xen_hvm_init(MachineState *machine)
     bus = pci_find_primary_bus();
     if (bus != NULL) {
         pci_create_simple(bus, -1, "xen-platform");
+        xen_igd_passthrough_isa_bridge_create(bus);
     }
 }
 #endif