I often run into situations where Linux tries to write to some extended capabilities. E.g., Linux wants to clear Advanced Error Reporting (ERR) registers when probing for a device.
At the moment, the crash dump of the cell is hard to interprete, as it remains unclear if the access is inside a capability, or if the device just accesses some PCI config space (e.g., accesses beyond PCI spec). At the moment, all extended capabilities have a fixed length of 4, which supports the confusion. Four bytes only cover the header of the capability. This patch calculates the correct length of PCI caps for the configuration file -- at least of some capabilities. For some extended caps this is pretty easy, as they have a fixed length. Nevertheless, other vary in their length. In some cases, it's pretty easy (VNDR, ACS), in other cases it's not worth it (VC, VC9) due to their complexity. Caps that aren't handle still result in a length of 4. Additionally, switch to a hexadecimal representation of the length of PCI caps in config files. Signed-off-by: Ralf Ramsauer <[email protected]> --- pyjailhouse/sysfs_parser.py | 35 +++++++++++++++++++++++++++++++---- tools/root-cell-config.c.tmpl | 2 +- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pyjailhouse/sysfs_parser.py b/pyjailhouse/sysfs_parser.py index 0a690186..a21690db 100644 --- a/pyjailhouse/sysfs_parser.py +++ b/pyjailhouse/sysfs_parser.py @@ -655,14 +655,41 @@ class PCICapability: id = PCI_EXT_CAP_ID(id) next = version_next >> 4 - if id == PCI_EXT_CAP_ID.SRIOV: + # access side effects still need to be analyzed + flags = PCICapability.RD + + if id == PCI_EXT_CAP_ID.VNDR: + (vsec_len,) = struct.unpack('<I', f.read(4)) + len = 4 + (vsec_len >> 20) + elif id == PCI_EXT_CAP_ID.ACS: + len = 8 + vector_size = 0 + + (acs_cap, acs_ctrl) = struct.unpack('<HH', f.read(4)) + if acs_cap & (1 << 5) and acs_ctrl & (1 << 5): + vector_bits = acs_cap >> 8 + if vector_bits == 0: + vector_bits = 256 + vector_bytes = int((vector_bits + 31) / (8 * 4)) + len += vector_bytes + elif id in [PCI_EXT_CAP_ID.VC, PCI_EXT_CAP_ID.VC9]: + # parsing is too complex, but we have at least 4 DWORDS + len = 4 * 4 + elif id == PCI_EXT_CAP_ID.MFVC: + len = 4 + elif id in [PCI_EXT_CAP_ID.LTR, PCI_EXT_CAP_ID.ARI, PCI_EXT_CAP_ID.PASID]: + len = 8 + elif id in [PCI_EXT_CAP_ID.DSN, PCI_EXT_CAP_ID.PTM]: + len = 12 + elif id in [PCI_EXT_CAP_ID.PWR, PCI_EXT_CAP_ID.SECPCI]: + len = 16 + elif id == PCI_EXT_CAP_ID.MCAST: + len = 48 + elif id in [PCI_EXT_CAP_ID.SRIOV, PCI_EXT_CAP_ID.ERR]: len = 64 - # access side effects still need to be analyzed - flags = PCICapability.RD else: # unknown/unhandled cap, mark its existence len = 4 - flags = PCICapability.RD f.seek(cap + 4) content = f.read(len - 4) caps.append(PCICapability(id, True, cap, len, flags, content, diff --git a/tools/root-cell-config.c.tmpl b/tools/root-cell-config.c.tmpl index 81d3a92b..512b9f0d 100644 --- a/tools/root-cell-config.c.tmpl +++ b/tools/root-cell-config.c.tmpl @@ -199,7 +199,7 @@ struct { { .id = ${c.gen_id_str()}, .start = ${hex(c.start)}, - .len = ${c.len}, + .len = ${hex(c.len)}, .flags = ${c.flags}, }, % endfor -- 2.22.0 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/20190711200915.21217-1-ralf.ramsauer%40oth-regensburg.de. For more options, visit https://groups.google.com/d/optout.
