For AMD, we also need to store the PCI address, capability offset and
IOMMU feature bits coming from ACPI (overwriting what the hardware
reports) in the cell configuration file.
Based on patches by Valentine Sinitsyn.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
{
.base = 0xfeb80000,
.size = 0x80000,
{
.base = 0xfeb80000,
.size = 0x80000,
+ .amd_bdf = 0x02,
+ .amd_base_cap = 0x40,
+ .amd_msi_cap = 0x54,
+ .amd_features = 0x80048824,
struct jailhouse_iommu {
__u64 base;
__u32 size;
struct jailhouse_iommu {
__u64 base;
__u32 size;
+ __u16 amd_bdf;
+ __u8 amd_base_cap;
+ __u8 amd_msi_cap;
+ __u32 amd_features;
} __attribute__((packed));
#define JAILHOUSE_SYSTEM_SIGNATURE "JAILSYST"
} __attribute__((packed));
#define JAILHOUSE_SYSTEM_SIGNATURE "JAILSYST"
def __init__(self, props):
self.base_addr = props['base_addr']
self.mmio_size = props['mmio_size']
def __init__(self, props):
self.base_addr = props['base_addr']
self.mmio_size = props['mmio_size']
+ if 'amd_bdf' in props:
+ self.amd_bdf = props['amd_bdf']
+ self.amd_base_cap = props['amd_base_cap']
+ self.amd_msi_cap = props['amd_msi_cap']
+ self.amd_features = props['amd_features']
+
+ @property
+ def is_amd_iommu(self):
+ return hasattr(self, 'amd_bdf')
def parse_iomem(pcidevices):
def parse_iomem(pcidevices):
raise RuntimeError('Too many IOMMU units. '
'Raise JAILHOUSE_MAX_IOMMU_UNITS.')
raise RuntimeError('Too many IOMMU units. '
'Raise JAILHOUSE_MAX_IOMMU_UNITS.')
for i, d in enumerate(pcidevices):
if d.bdf() == iommu_bdf:
for i, d in enumerate(pcidevices):
if d.bdf() == iommu_bdf:
+ # Extract MSI capability offset
+ for c in d.caps:
+ if c.id == 0x05:
+ msi_cap_ofs = c.start
# We must not map IOMMU to the cells
del pcidevices[i]
# We must not map IOMMU to the cells
del pcidevices[i]
+ if msi_cap_ofs is None:
+ raise RuntimeError('AMD IOMMU lacks MSI support, and '
+ 'Jailhouse doesn\'t support MSI-X yet.')
+
if (iommu_feat & (0xF << 13)) and (iommu_feat & (0x3F << 17)):
# Performance Counters are supported, allocate 512K
mmio_size = 524288
if (iommu_feat & (0xF << 13)) and (iommu_feat & (0x3F << 17)):
# Performance Counters are supported, allocate 512K
mmio_size = 524288
units.append(IOMMUConfig({
'base_addr': base_addr,
'mmio_size': mmio_size,
units.append(IOMMUConfig({
'base_addr': base_addr,
'mmio_size': mmio_size,
+ 'amd_bdf': iommu_bdf,
+ 'amd_base_cap': base_cap_ofs,
+ 'amd_msi_cap': msi_cap_ofs,
+ # IVHD block type 0x11 has exact EFR copy but type 0x10 may
+ # overwrite what hardware reports. Set reserved bit 0 in that
+ # case to indicate that the value is in use.
+ 'amd_features': (iommu_feat | 0x1) if block_type == 0x10 else 0
}))
bdf_start_range = None
}))
bdf_start_range = None
{
.base = ${hex(unit.base_addr)},
.size = ${hex(unit.mmio_size)},
{
.base = ${hex(unit.base_addr)},
.size = ${hex(unit.mmio_size)},
+ % if unit.is_amd_iommu:
+ .amd_bdf = ${hex(unit.amd_bdf)},
+ .amd_base_cap = ${hex(unit.amd_base_cap)},
+ .amd_msi_cap = ${hex(unit.amd_msi_cap)},
+ .amd_features = ${hex(unit.amd_features)},
+ % endif