Compare commits

...

16 commits
master ... dev

Author SHA1 Message Date
Filip Strajnar 8ba146d31e Check if iommu_group devices path exists, before listing it. 2024-10-27 10:18:40 +01:00
Filip Strajnar 0a346daaa7 Correctly assert existance of device. 2024-10-27 10:15:04 +01:00
Filip Strajnar 7e21cf58ea Driver name is now responsibility of PciDevice class instead of a separate function. 2024-10-27 10:14:34 +01:00
Filip Strajnar 8485c36218 Assert that PCI device with specified ID exists. 2024-10-27 10:06:09 +01:00
Filip Strajnar eb1bf1f273 Check if driver bind path exists before binding. 2024-10-27 09:56:52 +01:00
Filip Strajnar 29b007c2af Only unbind if device is bound to a driver. 2024-10-26 22:42:48 +02:00
Filip Strajnar 6c8f248e3e Added set_driver_override method. 2024-10-26 21:37:10 +02:00
Filip Strajnar 5a71e7611f Updated gitignore. 2024-10-26 20:44:36 +02:00
Filip Strajnar 605b40a8f7 Added methods vendor_code and device_code. 2024-10-26 20:40:20 +02:00
Filip Strajnar 6cc3a29828 Created unbind_driver and bind_to_driver. 2024-10-26 19:54:30 +02:00
Filip Strajnar 71b9ee9c58 Added devices_in_iommu_group method. 2024-10-26 19:40:49 +02:00
Filip Strajnar a29e8ba0ee Added method that checks if device is VGA. 2024-10-26 19:13:59 +02:00
Filip Strajnar 3e92aab2e7 Created PciDevice class. 2024-10-26 19:02:33 +02:00
Filip Strajnar 548527c302 Added a function that gets name of PCI device's driver. 2024-10-26 18:43:56 +02:00
Filip Strajnar 111caa2a5e Added convenience functions for PCI device and driver IDs. 2024-10-26 18:33:45 +02:00
Filip Strajnar b98b76d4e4 Ensure script is ran as root. 2024-10-26 18:25:37 +02:00
6 changed files with 101 additions and 0 deletions

2
.gitignore vendored
View file

@ -160,3 +160,5 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
/*util.sh

View file

@ -1,5 +1,10 @@
from sys import platform
from pci_passthrough_assist.permissions import is_ran_by_root
if platform != "linux":
print("This tool will only work on Linux based OS.")
exit(1)
if not is_ran_by_root():
print("This script needs to run as root.")
exit(1)

View file

@ -0,0 +1,9 @@
from os import listdir
def all_pci_device_ids() -> list[str]:
return listdir("/sys/bus/pci/devices")
def all_pci_driver_ids() -> list[str]:
return listdir("/sys/bus/pci/drivers")

View file

@ -0,0 +1,66 @@
from os.path import exists, realpath, basename
from os import listdir
class PciDevice:
def __init__(self, device_id: str):
assert exists(f"/sys/bus/pci/devices/{device_id}")
self.device_id = device_id
def driver_name(self) -> str:
pci_driver_path = f"/sys/bus/pci/devices/{self.device_id}/driver"
if not exists(pci_driver_path):
return "NO-DRIVER-BOUND"
driver_directory: str = realpath(pci_driver_path)
return basename(driver_directory)
def is_vga(self) -> bool:
return exists(f"/sys/bus/pci/devices/{self.device_id}/boot_vga")
def vendor_code(self, remove_prefix: bool = True) -> str:
with open(f"/sys/bus/pci/devices/{self.device_id}/vendor") as vendor:
return vendor.read() if not remove_prefix else vendor.read(
).lstrip("0x")
def device_code(self, remove_prefix: bool = True) -> str:
with open(f"/sys/bus/pci/devices/{self.device_id}/vendor") as device:
return device.read() if not remove_prefix else device.read(
).lstrip("0x")
def unbind_driver(self):
driver_unbind_path = f"/sys/bus/pci/devices/{self.device_id}/driver/unbind"
if not exists(driver_unbind_path):
print("Device is not bound to any driver.")
return
with open(driver_unbind_path, "w") as device_driver:
device_driver.write(self.device_id)
def set_driver_override(self, reserved_for_driver: str):
with open(f"/sys/bus/pci/devices/{self.device_id}/driver_override",
"w") as driver_override:
driver_override.write(reserved_for_driver)
def bind_to_driver(self, driver_to_bind: str, unbind_first: bool = True):
if unbind_first:
self.unbind_driver()
driver_bind_path = f"/sys/bus/pci/drivers/{driver_to_bind}/bind"
if not exists(driver_bind_path):
print(f"Can't bind to driver: {driver_bind_path}.")
return
with open(driver_bind_path, "w") as driver:
driver.write(self.device_id)
def devices_in_iommu_group(self) -> list['PciDevice']:
iommu_group_device_path = f"/sys/bus/pci/devices/{self.device_id}/iommu_group/devices"
if not exists(iommu_group_device_path):
print("Device does not have iommu_group devices.")
return []
device_ids: list[str] = listdir(iommu_group_device_path)
return [PciDevice(device_id) for device_id in device_ids]
def __str__(self) -> str:
return f"{self.device_id} driver: {self.driver_name()} VGA: {self.is_vga()}"

View file

@ -0,0 +1,5 @@
from pci_passthrough_assist.process_runner import sh
def is_ran_by_root() -> bool:
return sh(["whoami"]) == "root"

View file

@ -0,0 +1,14 @@
from subprocess import run
def sh_binary(args: list[str], ) -> bytes:
return run(args, capture_output=True).stdout
def sh(args: list[str], rstrip_newline=True):
string_output: str = sh_binary(args).decode()
return string_output if not rstrip_newline else string_output.rstrip("\n")
def sh_lines(args: list[str]) -> list[str]:
return sh(args, rstrip_newline=True).splitlines()