From: Michal Privoznik <[email protected]>

The VMX file also contains information on PCI topology. At least
for some devices. They have the .pciSlotNumber attribute which is
a number that encodes their PCI address. It's documented here
[1]. The algorithm described there also offers a way to calculate
PCI topology with bridges and everything. Let's save that for
future work. For now, just parse and report PCI address of SCSI
controllers.

NB: at this point it is unclear how the algorithm/address
encoding changes wrt 'virtualHW.version'. But we will cross that
bridge when we get there.

1: 
https://knowledge.broadcom.com/external/article/311606/mapping-pci-slot-numbers-to-guestvisible.html
Signed-off-by: Michal Privoznik <[email protected]>
---
 src/vmx/vmx.c                              | 40 ++++++++++++++++++++--
 tests/vmx2xmldata/esx-in-the-wild-11.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-12.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-13.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-14.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-16.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-17.xml   |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-5.xml    |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-6.xml    |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-7.xml    |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-8.xml    |  4 ++-
 tests/vmx2xmldata/esx-in-the-wild-9.xml    |  4 ++-
 tests/vmx2xmldata/fusion-in-the-wild-1.xml |  4 ++-
 13 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index c438f2720c..92b55307de 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -950,6 +950,34 @@ virVMXGetConfigBoolean(virConf *conf, const char *name, 
bool *boolean_,
 }
 
 
+static int
+virVMXPCISlotNumber(virConf *conf,
+                    const char *name,
+                    virDomainDeviceInfo *info)
+{
+    long long slotNumber = -1;
+
+    if (virVMXGetConfigLong(conf, name, &slotNumber, -1, true) < 0)
+        return -1;
+
+    if (slotNumber == -1) {
+        /* missing */
+        return 0;
+    }
+
+    /* The slot number encodes PCI address as FFF.BBBBB.DDDDD, for instance:
+     *   1216 = 0x4c0 = 001.00110.00000b
+     * which gives bus = 6, slot = 0, function = 1.
+     */
+    info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+    info->addr.pci.domain = 0;
+    info->addr.pci.bus = (slotNumber >> 5) & 0x1f;
+    info->addr.pci.slot = slotNumber & 0x1f;
+    info->addr.pci.function = (slotNumber >> 10) & 0x7;
+
+    return 0;
+}
+
 
 static int
 virVMXSCSIDiskNameToControllerAndUnit(const char *name, int *controller, int 
*unit)
@@ -2143,12 +2171,14 @@ virVMXParseSCSIController(virDomainDef *def,
                           int controllerIdx,
                           bool *present)
 {
+    virDomainControllerDef *controllerDef = NULL;
     int result = -1;
     char present_name[32];
     char virtualDev_name[32];
     char *virtualDev_string = NULL;
     char *tmp;
     int virtualDev = -1;
+    g_autofree char *pciSlotNumberName = NULL;
 
     if (controllerIdx < 0 || controllerIdx > 3) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -2194,11 +2224,15 @@ virVMXParseSCSIController(virDomainDef *def,
         }
     }
 
-    virDomainDefAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
-                              controllerIdx, virtualDev);
+    controllerDef = virDomainDefAddController(def, 
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
+                                              controllerIdx, virtualDev);
+
+    pciSlotNumberName = g_strdup_printf("scsi%d.pciSlotNumber", controllerIdx);
+
+    if (virVMXPCISlotNumber(conf, pciSlotNumberName, &controllerDef->info) < 0)
+        goto cleanup;
 
     result = 0;
-
  cleanup:
     VIR_FREE(virtualDev_string);
 
diff --git a/tests/vmx2xmldata/esx-in-the-wild-11.xml 
b/tests/vmx2xmldata/esx-in-the-wild-11.xml
index ded63c3345..e39a525de7 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-11.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-11.xml
@@ -32,7 +32,9 @@
       <target dev='sdbm' bus='scsi'/>
       <address type='drive' controller='1' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='scsi' index='1' model='vmpvscsi'/>
     <interface type='bridge'>
       <mac address='00:50:56:ac:3e:a1' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-12.xml 
b/tests/vmx2xmldata/esx-in-the-wild-12.xml
index 4836cbd03d..08a4b5fada 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-12.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-12.xml
@@ -31,7 +31,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='sata' index='0'/>
     <interface type='bridge'>
       <mac address='00:50:56:a0:cf:2f' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-13.xml 
b/tests/vmx2xmldata/esx-in-the-wild-13.xml
index 604fe99f5c..f38dc063f1 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-13.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-13.xml
@@ -36,7 +36,9 @@ package:20.6.2
       <target dev='sda' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='lsilogic'/>
+    <controller type='scsi' index='0' model='lsilogic'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x10' 
function='0x0'/>
+    </controller>
     <interface type='bridge'>
       <mac address='fa:16:3e:bb:2c:4a' type='static'/>
       <source bridge='Test'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-14.xml 
b/tests/vmx2xmldata/esx-in-the-wild-14.xml
index 31ada6eb5f..a8061b14c6 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-14.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-14.xml
@@ -25,7 +25,9 @@
       <target dev='sdb' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='0' unit='1'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <interface type='null'>
       <mac address='00:00:00:00:00:00' type='static'/>
       <model type='vmxnet3'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-16.xml 
b/tests/vmx2xmldata/esx-in-the-wild-16.xml
index 77c4a10c1c..2ff3a74d5f 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-16.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-16.xml
@@ -26,7 +26,9 @@
       <target dev='nvme0n1' bus='nvme'/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='nvme' index='0'/>
     <interface type='bridge'>
       <mac address='00:50:56:a0:a6:7e' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-17.xml 
b/tests/vmx2xmldata/esx-in-the-wild-17.xml
index 0603adfd35..04776efcea 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-17.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-17.xml
@@ -34,7 +34,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='lsisas1068'/>
+    <controller type='scsi' index='0' model='lsisas1068'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='sata' index='0'/>
     <interface type='bridge'>
       <mac address='00:50:56:a5:b8:68' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-5.xml 
b/tests/vmx2xmldata/esx-in-the-wild-5.xml
index fee496aa6a..fe3d81db63 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-5.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-5.xml
@@ -32,7 +32,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='lsilogic'/>
+    <controller type='scsi' index='0' model='lsilogic'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x10' 
function='0x0'/>
+    </controller>
     <controller type='ide' index='0'/>
     <interface type='bridge'>
       <mac address='00:50:56:be:00:15' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-6.xml 
b/tests/vmx2xmldata/esx-in-the-wild-6.xml
index ab3b1fa7a6..2682679796 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-6.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-6.xml
@@ -25,7 +25,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='1' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='ide' index='0'/>
     <interface type='bridge'>
       <mac address='00:0c:29:2c:3a:fc' type='generated'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-7.xml 
b/tests/vmx2xmldata/esx-in-the-wild-7.xml
index daaac5e92d..4cdf338640 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-7.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-7.xml
@@ -25,7 +25,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='1'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <interface type='bridge'>
       <mac address='00:50:56:9f:08:51' type='generated'/>
       <source bridge='VM Network'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-8.xml 
b/tests/vmx2xmldata/esx-in-the-wild-8.xml
index 3472ce14ef..5e92157c9d 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-8.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-8.xml
@@ -42,7 +42,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='scsi' index='0' model='vmpvscsi'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <controller type='sata' index='0'/>
     <interface type='bridge'>
       <mac address='00:1a:4a:16:01:55' type='static'/>
diff --git a/tests/vmx2xmldata/esx-in-the-wild-9.xml 
b/tests/vmx2xmldata/esx-in-the-wild-9.xml
index 57a376209b..7aff055ed3 100644
--- a/tests/vmx2xmldata/esx-in-the-wild-9.xml
+++ b/tests/vmx2xmldata/esx-in-the-wild-9.xml
@@ -26,7 +26,9 @@
       <target dev='sda' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='lsisas1068'/>
+    <controller type='scsi' index='0' model='lsisas1068'>
+      <address type='pci' domain='0x0000' bus='0x05' slot='0x00' 
function='0x0'/>
+    </controller>
     <interface type='bridge'>
       <mac address='00:50:56:80:b3:81' type='generated'/>
       <source bridge='VM Network'/>
diff --git a/tests/vmx2xmldata/fusion-in-the-wild-1.xml 
b/tests/vmx2xmldata/fusion-in-the-wild-1.xml
index a39bcbb2cd..2c29f65d77 100644
--- a/tests/vmx2xmldata/fusion-in-the-wild-1.xml
+++ b/tests/vmx2xmldata/fusion-in-the-wild-1.xml
@@ -24,7 +24,9 @@
       <readonly/>
       <address type='drive' controller='0' bus='0' target='0' unit='0'/>
     </disk>
-    <controller type='scsi' index='0' model='buslogic'/>
+    <controller type='scsi' index='0' model='buslogic'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x10' 
function='0x0'/>
+    </controller>
     <controller type='ide' index='0'/>
     <interface type='bridge'>
       <mac address='00:0c:29:3b:64:ea' type='generated'/>
-- 
2.54.0

Reply via email to