История изменений
Исправление dimon555, (текущая версия) :
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h> /* strcat */
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h> /* exit */
#include <unistd.h> /* getopt */
#include <inttypes.h>
#include <stdbool.h>
#include <linux/vfio.h>
int
main(int argc, char *argv[])
{
int opt;
char group_file[255] = "/dev/vfio/";
char dev_bdf[255];
int container, group, device, rc;
struct vfio_group_status group_status = {
.argsz = sizeof(group_status) };
typedef struct {
struct vfio_pci_hot_reset hotr;
__s32 group_fd;
} __attribute__((packed)) vfio_rst_data;
vfio_rst_data hot_rst;
while((opt = getopt(argc, argv, "g:s:")) != -1) {
switch(opt) {
case 'g':
strcat(group_file, optarg);
printf("group dev: %s\n", group_file);
break;
case 's':
strcpy(dev_bdf, optarg);
printf("device bdf: %s\n", dev_bdf);
break;
default:
fprintf(stderr, "Unknown option: %s\n", optarg);
exit(EXIT_FAILURE);
}
}
/* Open new container*/
container = open("/dev/vfio/vfio", O_RDWR);
rc = ioctl(container, VFIO_GET_API_VERSION);
printf("VFIO_GET_API_VERSION returned 0x%x, VFIO_API_VERSION = %d\n",
rc, VFIO_API_VERSION);
rc = ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU);
printf("VFIO_CHECK_EXTENSION returned 0x%x, VFIO_TYPE1_IOMMU = %d\n",
rc, VFIO_TYPE1_IOMMU);
/* Open group */
group = open(group_file, O_RDWR);
/* Test group */
ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
printf("iommu_group %s status: argsz=0x%x, flags=0x%x\n",
group_file, group_status.argsz, group_status.flags);
/* Add group to the container */
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
/* Enable IOMMU */
ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
/* Get a file descriptor for the device */
device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, dev_bdf);
hot_rst.hotr.argsz = sizeof(vfio_rst_data);
hot_rst.hotr.flags = 0;
hot_rst.hotr.count = 1;
hot_rst.group_fd = group;
/* Bus hot reset */
ioctl(device, VFIO_DEVICE_PCI_HOT_RESET, &hot_rst);
/* reset device */
printf("Device reset.\n");
ioctl(device, VFIO_DEVICE_RESET);
printf("IOMMU group unset container.\n");
ioctl(group, VFIO_GROUP_UNSET_CONTAINER, &container);
close(group);
close(container);
return 0;
}
потом нужно
gcc text.c -o vfio_reset
$ readlink /sys/bus/pci/devices/0000:01:00.0/iommu_group
(тут узнается число iommu group)
и потом
sudo ./vfio_reset -g 8 -s 0000:01:00.0
где 8 то самое число
этот конечный вариант не тестировал
от старого варианта остались всякие левые инклуды
главное это VFIO_DEVICE_PCI_HOT_RESET
проверь vfio.h на системе, чтобы он был
p.s. нужно ещё забайндить девайсы на vfio-pci драйвер
Исходная версия dimon555, :
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h> /* strcat */
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h> /* exit */
#include <unistd.h> /* getopt */
#include <inttypes.h>
#include <stdbool.h>
#include <linux/vfio.h>
int
main(int argc, char *argv[])
{
int opt;
char group_file[255] = "/dev/vfio/";
char dev_bdf[255];
int container, group, device, rc;
struct vfio_group_status group_status = {
.argsz = sizeof(group_status) };
typedef struct {
struct vfio_pci_hot_reset hotr;
__s32 group_fd;
} __attribute__((packed)) vfio_rst_data;
vfio_rst_data hot_rst;
while((opt = getopt(argc, argv, "g:s:")) != -1) {
switch(opt) {
case 'g':
strcat(group_file, optarg);
printf("group dev: %s\n", group_file);
break;
case 's':
strcpy(dev_bdf, optarg);
printf("device bdf: %s\n", dev_bdf);
break;
default:
fprintf(stderr, "Unknown option: %s\n", optarg);
exit(EXIT_FAILURE);
}
}
/* Open new container*/
container = open("/dev/vfio/vfio", O_RDWR);
rc = ioctl(container, VFIO_GET_API_VERSION);
printf("VFIO_GET_API_VERSION returned 0x%x, VFIO_API_VERSION = %d\n",
rc, VFIO_API_VERSION);
rc = ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU);
printf("VFIO_CHECK_EXTENSION returned 0x%x, VFIO_TYPE1_IOMMU = %d\n",
rc, VFIO_TYPE1_IOMMU);
/* Open group */
group = open(group_file, O_RDWR);
/* Test group */
ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
printf("iommu_group %s status: argsz=0x%x, flags=0x%x\n",
group_file, group_status.argsz, group_status.flags);
/* Add group to the container */
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
/* Enable IOMMU */
ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
/* Get a file descriptor for the device */
device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, dev_bdf);
hot_rst.hotr.argsz = sizeof(vfio_rst_data);
hot_rst.hotr.flags = 0;
hot_rst.hotr.count = 1;
hot_rst.group_fd = group;
/* Bus hot reset */
ioctl(device, VFIO_DEVICE_GET_PCI_HOT_RESET_INFO, &hot_rst);
/* reset device */
printf("Device reset.\n");
ioctl(device, VFIO_DEVICE_RESET);
printf("IOMMU group unset container.\n");
ioctl(group, VFIO_GROUP_UNSET_CONTAINER, &container);
close(group);
close(container);
return 0;
}
потом нужно
gcc text.c -o vfio_reset
$ readlink /sys/bus/pci/devices/0000:01:00.0/iommu_group
(тут узнается число iommu group)
и потом
sudo ./vfio_reset -g 8 -s 0000:01:00.0
где 8 то самое число
этот конечный вариант не тестировал
от старого варианта остались всякие левые инклуды
главное это VFIO_DEVICE_PCI_HOT_RESET
проверь vfio.h на системе, чтобы он был
p.s. нужно ещё забайндить девайсы на vfio-pci драйвер