WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [qemu-xen-unstable] passthrough: use devfn instead of sl

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] passthrough: use devfn instead of slots as the unit for pass-through
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Mon, 29 Jun 2009 03:01:10 -0700
Delivery-date: Mon, 29 Jun 2009 03:01:14 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
commit 7551a514dd944a5155747071135bac11deb61c43
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Thu Jun 25 18:30:25 2009 +0100

    passthrough: use devfn instead of slots as the unit for pass-through
    
    This is part of support for multi-function PCI devices in guests
    
    Instead of reading a slot number from xend, read a devfn.
    This and subsequent other changes will allow xend to ask
    for more than one function to be inserted into a single slot -
    by specifying which function of the slot should be used.
    
    This is a minimal patch for this change. A subsequent
    patch that has a lot of noise to rename slot to devfn follows.
    
    This patch breaks compatibility with xend and corresponding
    patches to xend are required.
    
    Cc: Dexuan Cui <dexuan.cui@xxxxxxxxx>
    Cc: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
    Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
    
    [3/8; cross-compatibility issues with xen-unstable.hg]
---
 hw/pass-through.c |   40 ++++++++++++++--------------
 hw/pci.h          |    7 +++-
 hw/piix4acpi.c    |   75 ++++++++++++++++++++++++++++++++++++++---------------
 3 files changed, 79 insertions(+), 43 deletions(-)

diff --git a/hw/pass-through.c b/hw/pass-through.c
index 07ca751..d19fb82 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -103,7 +103,7 @@ struct php_dev {
 };
 struct dpci_infos {
 
-    struct php_dev php_devs[NR_PCI_DEV];
+    struct php_dev php_devs[NR_PCI_DEVFN];
 
     PCIBus *e_bus;
     struct pci_access *pci_access;
@@ -859,7 +859,7 @@ static int parse_bdf(char **str, int *seg, int *bus, int 
*dev, int *func,
     }
     else
     {
-        *vslot = AUTO_PHP_SLOT;
+        *vslot = AUTO_PHP_DEVFN;
         *opt = token;
     }
 
@@ -903,30 +903,30 @@ static int pci_slot_match(int bus, int dev, int func, int 
slot)
 }
 
 /* Insert a new pass-through device into a specific pci slot.
- * input  dom:bus:dev.func@slot, chose free one if slot == AUTO_PHP_SLOT
+ * input  dom:bus:dev.func@slot, chose free one if slot == AUTO_PHP_DEVFN
  * return -2: requested slot not available
  *        -1: no free slots
  *        >=0: the new hotplug slot
  */
-static int __insert_to_pci_slot(int bus, int dev, int func, int slot,
+static int __insert_to_pci_slot(int bus, int dev, int func, int devfn,
                                 char *opt)
 {
     PCIBus *e_bus = dpci_infos.e_bus;
+    int slot;
 
-    /* preferred virt pci slot */
-    if ( slot != AUTO_PHP_SLOT)
+    /* preferred virt pci devfn */
+    if ( devfn != AUTO_PHP_DEVFN )
     {
-        if ( !test_pci_slot(slot) &&
-             !pci_devfn_in_use(e_bus, PCI_DEVFN(slot, 0)) )
+        if ( !test_pci_slot(devfn) && !pci_devfn_in_use(e_bus, devfn) )
             goto found;
         return -2;
     }
 
-    /* slot == 0, pick up a free one */
+    /* pick a free slot */
     for ( slot = 0; slot < NR_PCI_DEV; slot++ )
     {
-        if ( !test_pci_slot(slot) &&
-             !pci_devfn_in_use(e_bus, PCI_DEVFN(slot, 0)) )
+        devfn = PCI_DEVFN(slot, 0);
+        if ( !test_pci_slot(devfn) && !pci_devfn_in_use(e_bus, devfn) )
             goto found;
     }
 
@@ -934,12 +934,12 @@ static int __insert_to_pci_slot(int bus, int dev, int 
func, int slot,
     return -1;
 
 found:
-    dpci_infos.php_devs[slot].valid  = 1;
-    dpci_infos.php_devs[slot].r_bus  = bus;
-    dpci_infos.php_devs[slot].r_dev  = dev;
-    dpci_infos.php_devs[slot].r_func = func;
-    dpci_infos.php_devs[slot].opt = opt;
-    return slot;
+    dpci_infos.php_devs[devfn].valid  = 1;
+    dpci_infos.php_devs[devfn].r_bus  = bus;
+    dpci_infos.php_devs[devfn].r_dev  = dev;
+    dpci_infos.php_devs[devfn].r_func = func;
+    dpci_infos.php_devs[devfn].opt = opt;
+    return devfn;
 }
 
 /* Insert a new pass-through device into a specific pci slot.
@@ -966,7 +966,7 @@ int insert_to_pci_slot(char *bdf_slt)
  */
 int test_pci_slot(int slot)
 {
-    if ( slot < 0 || slot >= NR_PCI_DEV )
+    if ( slot < 0 || slot >= NR_PCI_DEVFN )
         return -1;
 
     if ( dpci_infos.php_devs[slot].valid )
@@ -987,7 +987,7 @@ int bdf_to_slot(char *bdf_str)
     }
 
     /* locate the virtual pci slot for this VTd device */
-    for ( i = 0; i < NR_PCI_DEV; i++ )
+    for ( i = 0; i < NR_PCI_DEVFN; i++ )
     {
         if ( pci_slot_match(bus, dev, func, i) )
             return i;
@@ -4037,7 +4037,7 @@ static struct pt_dev * register_real_device(PCIBus *e_bus,
 
     /* Register device */
     assigned_device = (struct pt_dev *) pci_register_device(e_bus, e_dev_name,
-                                sizeof(struct pt_dev), PCI_DEVFN(e_slot, 0),
+                                sizeof(struct pt_dev), e_slot,
                                 pt_pci_read_config, pt_pci_write_config);
     if ( assigned_device == NULL )
     {
diff --git a/hw/pci.h b/hw/pci.h
index d45b80c..b5947f3 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -255,8 +255,11 @@ void pci_info(void);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
                         pci_map_irq_fn map_irq, const char *name);
 
-#define NR_PCI_DEV 32
-#define AUTO_PHP_SLOT NR_PCI_DEV
+#define NR_PCI_FUNC    8
+#define NR_PCI_DEV     32
+#define NR_PCI_DEVFN   (NR_PCI_FUNC * NR_PCI_DEV)
+#define AUTO_PHP_SLOT  NR_PCI_DEV
+#define AUTO_PHP_DEVFN NR_PCI_DEVFN
 
 int insert_to_pci_slot(char*);
 int test_pci_slot(int);
diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
index d5c5c35..836abd5 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -33,6 +33,8 @@
 #include <xen/hvm/ioreq.h>
 #include <xen/hvm/params.h>
 
+#include <pci/header.h>
+
 /* PM1a_CNT bits, as defined in the ACPI specification. */
 #define SCI_EN            (1 <<  0)
 #define GBL_RLS           (1 <<  2)
@@ -276,7 +278,7 @@ static void acpi_php_writeb(void *opaque, uint32_t addr, 
uint32_t val)
             hotplug_slots->plug_slot = 0;
 
             /* power off the slot */
-            power_off_php_slot(slot);
+            power_off_php_slot(PCI_DEVFN(slot, 0));
 
             /* signal the CP ACPI hot remove done. */
             xenstore_record_dm_state("pci-removed");
@@ -459,17 +461,32 @@ static void acpi_sci_intr(GPEState *s)
     }
 }
 
-void acpi_php_del(int slot)
+void acpi_php_del(int devfn)
 {
     GPEState *s = &gpe_state;
+    int slot, func;
+
+    slot = PCI_SLOT(devfn);
+    func = PCI_FUNC(devfn);
 
-    if ( test_pci_slot(slot) < 0 ) {
-        fprintf(logfile, "hot remove: pci slot %d "
-                "is not used by a hotplug device.\n", slot);
+    if ( test_pci_slot(devfn) < 0 ) {
+        fprintf(logfile, "hot remove: pci slot 0x%02x, function 0x%x "
+                "is not used by a hotplug device.\n", slot, func);
 
         return;
     }
 
+    /* ACPI PHP can only work on slots
+     * So only remove zero-functions -
+     * which will remove all other fucntions of the same device in the
+     * guest.
+     */
+    if ( func ) {
+        fprintf(logfile, "hot remove: Attempt to remove non-zero function "
+                "slot=0x%02x func=0x%0x.\n", slot, func);
+        return;
+    }
+
     /* update the php controller status */
     php_slots.plug_evt = PHP_EVT_REMOVE;
     php_slots.plug_slot = slot;
@@ -478,18 +495,19 @@ void acpi_php_del(int slot)
     acpi_sci_intr(s);
 }
 
-void acpi_php_add(int slot)
+void acpi_php_add(int devfn)
 {
     GPEState *s = &gpe_state;
     char ret_str[30];
+    int slot, func;
 
-    if ( slot < 0 ) {
-        fprintf(logfile, "hot add pci slot %d exceed.\n", slot);
+    if ( devfn < 0 ) {
+        fprintf(logfile, "hot add pci devfn %d exceed.\n", devfn);
 
-        if ( slot == -1 )
-            sprintf(ret_str, "no free hotplug slots");
-        else if ( slot == -2 )
-            sprintf(ret_str, "wrong bdf or vslot");
+        if ( devfn == -1 )
+            sprintf(ret_str, "no free hotplug devfn");
+        else if ( devfn == -2 )
+            sprintf(ret_str, "wrong bdf or vdevfn");
 
         if ( strlen(ret_str) > 0 )
             xenstore_record_dm("parameter", ret_str);
@@ -497,25 +515,40 @@ void acpi_php_add(int slot)
         return;
     }
 
-    /* update the php controller status */
-    php_slots.plug_evt = PHP_EVT_ADD;
-    php_slots.plug_slot = slot;
+    /* ACPI PHP can only work on slots
+     * For function 0 we do a full hot-add.
+     * For other functions we just register the device with the hypervisor.
+     * Assuming that function 0 is added after non-zero functions,
+     * its ACPI PHP event will cause all previously registered functions
+     * to be added to the guest.
+     */
 
-    /* update the slot status as present */
-    php_slots.status[slot] = 0xf;
+    slot = PCI_SLOT(devfn);
+    func = PCI_FUNC(devfn);
 
-    /* power on the slot */
-    power_on_php_slot(slot);
+    if ( !func )
+    {
+        /* update the php controller status */
+        php_slots.plug_evt = PHP_EVT_ADD;
+        php_slots.plug_slot = slot;
+
+        /* update the slot status as present */
+        php_slots.status[slot] = 0xf;
+    }
+
+    /* power on the function */
+    power_on_php_slot(devfn);
 
     /* tell Control panel which slot for the new pass-throgh dev */
-    sprintf(ret_str, "0x%02x", slot);
+    sprintf(ret_str, "0x%02x", devfn);
     xenstore_record_dm("parameter", ret_str);
 
     /* signal the CP ACPI hot insert done */
     xenstore_record_dm_state("pci-inserted");
 
     /* generate a SCI interrupt */
-    acpi_sci_intr(s);
+    if ( !func )
+        acpi_sci_intr(s);
 }
 
 #endif /* CONFIG_PASSTHROUGH */
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] passthrough: use devfn instead of slots as the unit for pass-through, Ian Jackson <=