FW: About the patch ”https://lore.kernel.org/linux-iommu/20240412082121.33382-1-yi.l.liu@xxxxxxxxx/ “ for help

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



DEAR ALL ,

 

No  I  have know the root cause ,  the issue  ouccured when below code run my AMD test PC.

 

So  could you guys  give  some suggestion ?  Will very much appreciate if you feel free to reply!!

 

 

From: XueMei Yue
Sent: 2024
722 9:50
To: yi.l.liu@xxxxxxxxx
Subject: About the patch ”https://lore.kernel.org/linux-iommu/20240412082121.33382-1-yi.l.liu@xxxxxxxxx/ “ for help

 

hi, 

I am an firmware engineer from china . I want to test the function ATS that need the support of iommufd+pasid

Now I will test some new function will use pasid +  iommufd

i used your patch from  https://lore.kernel.org/linux-iommu/20240412082121.33382-1-yi.l.liu@xxxxxxxxx/

my test step is 

1  use spdk   run   ./scripts/setup,  the nvme device drive is changed from nvme to vfio-pci 

2  run my example see the attchment using g++ to compile

when run my  example . the below error occurs could you give some suggestion

[ root@hippo ./iommufd.o 
Program ./iommufd.o 
the map va is : 7fe866435ØØØ, the iova is O, the size is 1048576 
VFIO DEVICE PASID ATTACH IOMMUFD PT failed! error is operation not supported 
[rooQ@hippo xuemei]#

Will very much appreciate if you feel free to reply!!

 

Best regards

XueMei

 

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <linux/vfio.h>
#include <inttypes.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string>
#include <iostream>
#include <cstring>
#include <linux/iommufd.h>
 
struct args
{
	__u64	iova;				/* IO virtual address */
	__u64	size;
	std::string vfioX;
	std::string bdf;

};
int main(int argc, char *argv[]) 
{
    int ret = 0;
	int cdev_fd, iommufd, i;
	
    std::cout << "Program name: " << argv[0] << std::endl;
		struct args para={0};
    for (int i = 1; i < argc; ++i) 
	{
	
        std::cout << "Argument " << i << ": " << argv[i] << std::endl;
		if(!std::strcmp(argv[i], "-help"))
		{
		    printf("-iova:         input the map address iova\n");
			printf("-size:         input the Number of bytes to copy and map\n");
			printf("-device:       input the bdf\n");
			printf("-vfio  :       input the vfioX\n");
			return 0;	
		}
		if(!std::strcmp(argv[i], "-iova"))
		{
			i++;
			char *address = argv[i];
			sscanf(address, "%" SCNx64, &para.iova);
			printf("The address is: %" PRIx64 "\n", para.iova);
		}
		if(!std::strcmp(argv[i], "-size"))
		{
		    i++;
			para.size = atoi(argv[i]);
            std::cout << "the size is "<< para.size << std::endl;
		}
		if(!std::strcmp(argv[i], "-vfio"))
		{
		  	i++;
			para.vfioX = argv[i];
            std::cout << "vfioX is "<< para.vfioX << std::endl;

		}
        if(!std::strcmp(argv[i] ,  "-device"))
		{
		    i++;
			char *input_string = argv[i];
			para.bdf = input_string ;
		}
			
    }
	
	
	struct vfio_device_bind_iommufd bind = {
        .argsz = sizeof(bind),
        .flags = 0,
    };
     struct iommu_ioas_alloc alloc_data  = {
        .size = sizeof(alloc_data),
        .flags = 0,
     };
     struct vfio_device_attach_iommufd_pt attach_data = {
        .argsz = sizeof(attach_data),
        .flags = 0,
     };
    struct iommu_ioas_map map = {
        .size = sizeof(map),
        .flags = IOMMU_IOAS_MAP_READABLE |
                 IOMMU_IOAS_MAP_WRITEABLE |
                 IOMMU_IOAS_MAP_FIXED_IOVA,
        .__reserved = 0,
    };
	struct iommu_ioas_unmap unmap = {
		.size = sizeof(unmap),
	};
	struct vfio_device_pasid_attach_iommufd_pt pasid = {
		.argsz = sizeof(pasid),
        .flags = 0,
	};
	
	struct vfio_device_pasid_detach_iommufd_pt detach_pasid = {
		.argsz = sizeof(detach_pasid),
        .flags = 0,
	};


    /* Open the group */
    std::string vfio;
    if(!para.vfioX.empty())
    {
	    vfio = "/dev/vfio/devices/" + para.vfioX;
    }
    else 
    {
        vfio = "/dev/vfio/devices/vfio0";
    }
    cdev_fd = open(vfio.c_str(), O_RDWR);
    iommufd = open("/dev/iommu", O_RDWR);

    if (cdev_fd < 0 || iommufd <0) 
    {
	    /* if file not found, it's not an error */
	    if (errno != ENOENT) 
		{
	        std::cout << "Cannot open "<< iommufd  << " or  "<< cdev_fd <<" , error is : " <<  strerror(errno);
	        return -1;
	    } 
    }
    bind.iommufd = iommufd;

    if(ioctl(cdev_fd, VFIO_DEVICE_BIND_IOMMUFD, &bind))
    {
	std::cout << "VFIO_DEVICE_BIND_IOMMUFD failed! "<<strerror(errno)<<std::endl;
        return 1;
    }

    if(ioctl(iommufd, IOMMU_IOAS_ALLOC, &alloc_data))
    {
        std::cout << "IOMMU_IOAS_ALLOC failed! "<< strerror(errno) << std::endl ;
        return 1;
    }
	
    attach_data.pt_id = alloc_data.out_ioas_id;
    if(ioctl(cdev_fd, VFIO_DEVICE_ATTACH_IOMMUFD_PT, &attach_data))
    {
	std::cout << "VFIO_DEVICE_ATTACH_IOMMUFD_PT failed! "<< std::endl;
        return 1;
    }

    /* Allocate some space and setup a DMA mapping */
	
	map.length = 1024 * 1024;
    map.iova = 0; /* 1MB starting at 0x0 from device view */
	if(para.size)
    {
	    map.length = para.size; 
    }
    if(para.iova!= map.iova)
    {
	    map.iova = para.iova;  /* 1MB starting at 0x0 from device view */
    }
    map.user_va = (int64_t)mmap(0, map.length, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

    map.ioas_id = alloc_data.out_ioas_id;

    printf("the map va is : %llx,the iova is % llx,the size is %d\n",map.user_va,map.iova,map.length);
    if(ioctl(iommufd, IOMMU_IOAS_MAP, &map))
    {
	std::cout << "IOMMU_IOAS_MAP failed! "<< std::endl;
        return 1;
    }

    /*attachAssociate a pasid (of a cdev device) with an address space within the bound iommufd*/
    pasid.pasid = 0;
    pasid.pt_id = alloc_data.out_ioas_id;
    if(ioctl(cdev_fd, VFIO_DEVICE_PASID_ATTACH_IOMMUFD_PT, &pasid))
    {
	std::cout << "VFIO_DEVICE_PASID_ATTACH_IOMMUFD_PT failed! error is "<<strerror(errno)<< std::endl;
        return 1;
    }
     /*attachAssociate a pasid (of a cdev device) with an address space within the bound iommufd*/
    pasid.pasid = 1;
    pasid.pt_id = alloc_data.out_ioas_id;
    if(ioctl(cdev_fd, VFIO_DEVICE_PASID_ATTACH_IOMMUFD_PT, &pasid))
    {
        std::cout << "VFIO_DEVICE_PASID_ATTACH_IOMMUFD_PT failed! "<< std::endl;
        return 1;
    }
    
	
    while(1)
    {
        char input[5];
	sleep(150);
	printf("could you want EXIT ?enter [yes|no]? : ");
        scanf("%s", input);
	if(!std::strcmp(input, "yes"))
	{
	     break;
	}
    }
	
    detach_pasid.pasid = alloc_data.out_ioas_id;
    if(ioctl(cdev_fd, VFIO_DEVICE_PASID_DETACH_IOMMUFD_PT, &detach_pasid))
    {
	std::cout << "VFIO_DEVICE_PASID_DETACH_IOMMUFD_PT failed! "<< std::endl;
        return 1;
    }
	
	/*DMA unmapping */
	unmap.ioas_id = map.ioas_id;
	unmap.iova = map.iova;
	unmap.length = map.length;
	if(ioctl(iommufd, IOMMU_IOAS_UNMAP, &unmap))
    {
	    std::cout << "IOMMU_IOAS_UNMAP failed! "<< std::endl;
        return 1;
    }

    sleep(150);
	
    return 0;

/* Other device operations as stated in "VFIO Usage Example" */
}





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux