Skip to content
Permalink
Browse files

pyjailhouse: let the generator produce speaking names for PCI caps

Definitions on C-side are in place, so let the generator produce those
definitions.

Therefore, we autogenerate pyjailhouse/pci_defs.py.

The generator will extract PCI_CAP_IDs with grep & sed, fill the template and
print the generated python file. The Makefile will redirect the output to the
final destination.

Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
[Jan: moved pci_defs.py generation, refactored extended caps ID string]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  • Loading branch information...
rralf authored and jan-kiszka committed May 9, 2019
1 parent b71a700 commit eee55f900948e5fe0c840ccfe2036444dd45bf7f
Showing with 81 additions and 19 deletions.
  1. +1 −0 .gitignore
  2. +13 −1 Kbuild
  3. +1 −1 Makefile
  4. +21 −12 pyjailhouse/sysfs_parser.py
  5. +44 −0 scripts/gen_pci_defs.sh
  6. +1 −5 tools/root-cell-config.c.tmpl
@@ -19,6 +19,7 @@ include/jailhouse/config.h
hypervisor/hypervisor.lds
inmates/lib/arm/inmate.lds
inmates/lib/arm64/inmate.lds
pyjailhouse/pci_defs.py
tools/jailhouse
tools/jailhouse-gcov-extract
tools/jailhouse-config-collect
14 Kbuild
@@ -41,6 +41,16 @@ GEN_VERSION_H := $(obj)/hypervisor/include/generated/version.h
$(GEN_VERSION_H): $(src)/Makefile FORCE
$(call filechk,version)

quiet_cmd_gen_pci_defs = GEN $@
define cmd_gen_pci_defs
$^ $(src)/include/jailhouse/pci_defs.h > $@
endef

GEN_PCI_DEFS_PY := $(obj)/pyjailhouse/pci_defs.py

$(GEN_PCI_DEFS_PY): $(src)/scripts/gen_pci_defs.sh
$(call if_changed,gen_pci_defs)

subdir-y := driver hypervisor configs inmates tools

subdir-ccflags-y := -Werror
@@ -52,9 +62,11 @@ $(addprefix $(obj)/,$(subdir-y)): $(GEN_CONFIG_MK)

$(obj)/driver $(obj)/hypervisor: $(GEN_VERSION_H)

$(obj)/tools: $(GEN_PCI_DEFS_PY)

endif

clean-files := pyjailhouse/*.pyc
clean-files := pyjailhouse/*.pyc pyjailhouse/pci_defs.py

clean-dirs := Documentation/generated hypervisor/include/generated \
pyjailhouse/__pycache__
@@ -59,4 +59,4 @@ ifeq ($(strip $(PYTHON_PIP_USABLE)), yes)
endif

.PHONY: modules_install install clean firmware_install modules tools docs \
docs_clean pyjailhouse_install
docs_clean
@@ -22,6 +22,8 @@
import os
import fnmatch

from .pci_defs import PCI_CAP_ID, PCI_EXT_CAP_ID

root_dir = "/"


@@ -368,7 +370,7 @@ def format_bdf(bdf):
if d.bdf() == iommu_bdf:
# Extract MSI capability offset
for c in d.caps:
if c.id == 0x05:
if c.id == PCI_CAP_ID.MSI:
msi_cap_ofs = c.start
# We must not map IOMMU to the cells
del pcidevices[i]
@@ -543,8 +545,9 @@ def __init__(self, dir):


class PCICapability:
def __init__(self, id, start, len, flags, content, msix_address):
def __init__(self, id, extended, start, len, flags, content, msix_address):
self.id = id
self.extended = extended
self.start = start
self.len = len
self.flags = flags
@@ -556,6 +559,10 @@ def __eq__(self, other):
return self.id == other.id and self.start == other.start and \
self.len == other.len and self.flags == other.flags

def gen_id_str(self):
return str(self.id) + \
(' | JAILHOUSE_PCI_EXT_CAP' if self.extended else '')

RD = '0'
RW = 'JAILHOUSE_PCICAPS_WRITE'

@@ -580,11 +587,12 @@ def parse_pcicaps(dir):
msix_address = 0
f.seek(cap)
(id, next) = struct.unpack('<BB', f.read(2))
if id == 0x01: # Power Management
id = PCI_CAP_ID(id)
if id == PCI_CAP_ID.PM:
# this cap can be handed out completely
len = 8
flags = PCICapability.RW
elif id == 0x05: # MSI
elif id == PCI_CAP_ID.MSI:
# access will be moderated by hypervisor
len = 10
(msgctl,) = struct.unpack('<H', f.read(2))
@@ -593,15 +601,15 @@ def parse_pcicaps(dir):
if (msgctl & (1 << 8)) != 0: # per-vector masking support
len += 10
flags = PCICapability.RW
elif id == 0x10: # Express
elif id == PCI_CAP_ID.EXP:
len = 20
(cap_reg,) = struct.unpack('<H', f.read(2))
if (cap_reg & 0xf) >= 2: # v2 capability
len = 60
# access side effects still need to be analyzed
flags = PCICapability.RD
has_extended_caps = True
elif id == 0x11: # MSI-X
elif id == PCI_CAP_ID.MSIX:
# access will be moderated by hypervisor
len = 12
(table,) = struct.unpack('<xxI', f.read(6))
@@ -620,7 +628,7 @@ def parse_pcicaps(dir):
flags = PCICapability.RD
f.seek(cap + 2)
content = f.read(len - 2)
caps.append(PCICapability(id, cap, len, flags, content,
caps.append(PCICapability(id, False, cap, len, flags, content,
msix_address))

if has_extended_caps:
@@ -637,8 +645,9 @@ def parse_pcicaps(dir):
'Extended Capability ID %x' % id)
continue

id = PCI_EXT_CAP_ID(id)
next = version_next >> 4
if id == 0x0010: # SR-IOV
if id == PCI_EXT_CAP_ID.SRIOV:
len = 64
# access side effects still need to be analyzed
flags = PCICapability.RD
@@ -648,8 +657,8 @@ def parse_pcicaps(dir):
flags = PCICapability.RD
f.seek(cap + 4)
content = f.read(len - 4)
id |= PCICapability.JAILHOUSE_PCI_EXT_CAP
caps.append(PCICapability(id, cap, len, flags, content, 0))
caps.append(PCICapability(id, True, cap, len, flags, content,
0))

f.close()
return caps
@@ -674,9 +683,9 @@ def __init__(self, type, domain, bus, dev, fn, bars, caps, path):
self.msix_region_size = 0
self.msix_address = 0
for c in caps:
if c.id in (0x05, 0x11):
if c.id in (PCI_CAP_ID.MSI, PCI_CAP_ID.MSIX):
msg_ctrl = struct.unpack('<H', c.content[:2])[0]
if c.id == 0x05: # MSI
if c.id == PCI_CAP_ID.MSI:
self.num_msi_vectors = 1 << ((msg_ctrl >> 1) & 0x7)
self.msi_64bits = (msg_ctrl >> 7) & 1
else: # MSI-X
@@ -0,0 +1,44 @@
#!/bin/bash
#
# Jailhouse, a Linux-based partitioning hypervisor
#
# Copyright (c) OTH Regensburg, 2019
#
# Authors:
# Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de>
#
# This work is licensed under the terms of the GNU GPL, version 2. See
# the COPYING file in the top-level directory.

CELL_CONFIG_H=$1

function find_defines() {
header=$1
prefix=$2
search="#define\s\+${prefix}\(\S*\)\s\+\(\S*\).*"
replace=" '\1'\t: \2,"

grep $prefix $header | sed -e "s/$search/$replace/"
}

PCI_CAP_IDS=$(find_defines $CELL_CONFIG_H PCI_CAP_ID_)
PCI_EXT_CAP_IDS=$(find_defines $CELL_CONFIG_H PCI_EXT_CAP_ID_)

cat <<END
# This file is autogenerated. If you need to change it, edit
# tools/gen_pci_cap_ids.py.sh instead.
from .extendedenum import ExtendedEnum
class PCI_CAP_ID(ExtendedEnum):
_ids = {
${PCI_CAP_IDS}
}
class PCI_EXT_CAP_ID(ExtendedEnum):
_ids = {
${PCI_EXT_CAP_IDS}
}
END
@@ -196,11 +196,7 @@ struct {
/* ${comment} */
% endfor
{
% if (c.id & 0x8000) != 0:
.id = ${hex(c.id & 0x7fff)} | JAILHOUSE_PCI_EXT_CAP,
% else:
.id = ${hex(c.id)},
% endif
.id = ${c.gen_id_str()},
.start = ${hex(c.start)},
.len = ${c.len},
.flags = ${c.flags},

0 comments on commit eee55f9

Please sign in to comment.
You can’t perform that action at this time.