]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
configs/tools: Provide MSI-X parameters via config
authorJan Kiszka <jan.kiszka@siemens.com>
Thu, 14 Aug 2014 17:59:19 +0000 (19:59 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Tue, 26 Aug 2014 17:56:49 +0000 (19:56 +0200)
It is simpler to calculate and validate these offline than to do it
during hypervisor setup.

Add the new information to the QEMU config file.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
configs/qemu-vm.c
hypervisor/include/jailhouse/cell-config.h
tools/jailhouse-config-create
tools/root-cell-config.c.tmpl

index 45cf0a4392be12d5a61f595236f31a6a3c955b50..7fe3d4b7ea4f1c52ce43510cea4ac284549ab3b8 100644 (file)
@@ -135,6 +135,9 @@ struct {
                        .bdf = 0x0018,
                        .caps_start = 0,
                        .num_caps = 1,
+                       .num_msix_vectors = 2,
+                       .msix_region_size = 0x1000,
+                       .msix_address = 0xfebf1000,
                },
                { /* ISA bridge */
                        .type = JAILHOUSE_PCI_TYPE_DEVICE,
index b5eca7e327628ccf00c415b9a84ace865151fd9f..b01d6b5dfbc9e09f12e77d67b8b0ce4c92f12bbc 100644 (file)
@@ -60,14 +60,16 @@ struct jailhouse_irqchip {
 #define JAILHOUSE_PCI_TYPE_BRIDGE      0x02
 
 struct jailhouse_pci_device {
-       __u32 type;
+       __u16 type;
        __u16 domain;
        __u16 bdf;
        __u16 caps_start;
        __u16 num_caps;
        __u8 num_msi_vectors;
        __u8 msi_64bits;
-       __u16 padding;
+       __u16 num_msix_vectors;
+       __u16 msix_region_size;
+       __u64 msix_address;
 } __attribute__((packed));
 
 #define JAILHOUSE_PCICAPS_WRITE                0x0001
index beb2acbea045dcbb0645edf2dec89b0ae8676a92..e6cbe0fb6725e852e23fc33af006b3c9ecc80a1c 100755 (executable)
@@ -111,12 +111,13 @@ def input_listdir(dir, wildcards):
 
 
 class PCICapability:
-    def __init__(self, id, start, len, flags, content):
+    def __init__(self, id, start, len, flags, content, msix_address):
         self.id = id
         self.start = start
         self.len = len
         self.flags = flags
         self.content = content
+        self.msix_address = msix_address
         self.comments = []
 
     def __eq__(self, other):
@@ -141,6 +142,7 @@ class PCICapability:
         (next,) = struct.unpack('B', f.read(1))
         while next != 0:
             cap = next
+            msix_address = 0
             f.seek(cap)
             (id, next) = struct.unpack('<BB', f.read(2))
             if id == 0x01:  # Power Management
@@ -159,6 +161,14 @@ class PCICapability:
             elif id == 0x11:  # MSI-X
                 # access will be moderated by hypervisor
                 len = 12
+                (table,) = struct.unpack('<xxI', f.read(6))
+                f.seek(0x10 + (table & 7) * 4)
+                (bar,) = struct.unpack('<I', f.read(4))
+                if (bar & 0x3) != 0:
+                    raise RuntimeError('Invalid MSI-X BAR found')
+                if (bar & 0x4) != 0:
+                    bar |= struct.unpack('<I', f.read(4))[0] << 32
+                msix_address = (bar & 0xfffffffffffffff0) + table & 0xfffffff8
                 flags = PCICapability.RW
             else:
                 # unknown/unhandled cap, mark its existence
@@ -166,7 +176,8 @@ class PCICapability:
                 flags = PCICapability.RD
             f.seek(cap + 2)
             content = f.read(len - 2)
-            caps.append(PCICapability(id, cap, len, flags, content))
+            caps.append(PCICapability(id, cap, len, flags, content,
+                                      msix_address))
         return caps
 
 
@@ -182,12 +193,20 @@ class PCIDevice:
         self.num_caps = len(caps)
         self.num_msi_vectors = 0
         self.msi_64bits = 0
+        self.num_msix_vectors = 0
+        self.msix_region_size = 0
+        self.msix_address = 0
         for c in caps:
             if c.id in (0x05, 0x11):
                 msg_ctrl = struct.unpack('<H', c.content[:2])[0]
                 if c.id == 0x05:  # MSI
                     self.num_msi_vectors = 1 << ((msg_ctrl >> 1) & 0x7)
                     self.msi_64bits = (msg_ctrl >> 7) & 1
+                else:  # MSI-X
+                    vectors = (msg_ctrl & 0x7ff) + 1
+                    self.num_msix_vectors = vectors
+                    self.msix_region_size = (vectors * 16 + 0xfff) & 0xf000
+                    self.msix_address = c.msix_address
 
     def __str__(self):
         return 'PCIDevice: %02x:%02x.%x' % (self.bus, self.dev, self.fn)
index 8e7f3a13f920ee876070ce65a53d3b57a54133f7..c0a09ec46f6301e16e1fdff38f0e75644f9f9342 100644 (file)
@@ -113,6 +113,9 @@ struct {
                        .num_caps = ${d.num_caps},
                        .num_msi_vectors = ${d.num_msi_vectors},
                        .msi_64bits = ${d.msi_64bits},
+                       .num_msix_vectors = ${d.num_msix_vectors},
+                       .msix_region_size = ${hex(d.msix_region_size)},
+                       .msix_address = ${hex(d.msix_address).strip('L')},
                },
                % endfor
        },