$uuid, 'mac' => $mac]); $best = null; foreach ($res as $row) { if ($best === null || $best['lastseen'] < $row['lastseen']) { $best = $row; } } if ($best === null) return ''; $hw = new HardwareQuery(self::PCI_DEVICE, $best['machineuuid'], true); // TODO: Get list of enabled pass through groups for this client's location $hw->addWhere(true, '@PASSTHROUGH', 'IN', ['GPU', 'GVT']); $hw->addGlobalColumn('vendor'); $hw->addGlobalColumn('device'); $hw->addLocalColumn('slot'); $res = $hw->query(); $passthrough = []; $slots = []; $gvt = false; foreach ($res as $row) { if ($row['@PASSTHROUGH'] === 'GVT') { $gvt = true; } else { $passthrough[$row['vendor'] . ':' . $row['device']] = 1; //error_log('Passthouorgh: ' . $row['vendor'] . ':' . $row['device']); $slots[preg_replace('/\.[0-9]+$/', '', $row['slot'])] = 1; } } $kcl = ''; if ($gvt || !empty($passthrough)) { $kcl = '-iommu -intel_iommu iommu=pt intel_iommu=on'; // TODO AMD } if (!empty($passthrough)) { foreach (array_keys($slots) as $slot) { //error_log('Querying slot ' . $slot); $hw = new HardwareQuery(self::PCI_DEVICE, $best['machineuuid'], true); $hw->addWhere(false, 'slot', 'LIKE', $slot . '.%'); $hw->addGlobalColumn('vendor'); $hw->addGlobalColumn('device'); foreach ($hw->query() as $row) { $passthrough[$row['vendor'] . ':' . $row['device']] = 1; //error_log('Extra PT: ' . $row['vendor'] . ':' . $row['device']); } } $kcl .= ' vfio-pci.ids=' . implode(',', array_keys($passthrough)); } if ($gvt) { $kcl .= ' i915.enable_gvt=1'; } return $kcl; } }