lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sat, 2 Jul 2011 02:05:41 +0200
From:	newton mailinglist <newtonmailinglist@...il.com>
To:	linux-kernel@...r.kernel.org
Subject: [PCI Driver]Physical address being returned as 0 in mmap

Hi,

I have written a PCI driver for my device. The device is an FPGA which
is configured with a design that allows it to have direct access to
memory of a host computer to which the fpga board is connected. My
device driver is responsible for translating virtual addresses to
physical addresses and sending these to the FPGA so the DMA unit in
the FPGA can directly access pages in memory using the physical
address.

I want to send about 1 MB of data to the FPGA. I currently 1st mmap
the required data file in my c program as follows :

//Open the bitstream file
	int fd = open(filename, O_RDWR);
	if (fd < 0){
		perror("molen_set : Filename Open");
		return;
	}
	
	//Get bitstream file size
	fstat(fd, &buf);
	length = buf.st_size;
	if(length == 0){
		fprintf(stderr, "\nmolen_set : Empty input file\n");
		return;
	}
	
	//Map bitstream file to memory to read it in via page faults(faster
than explicit file I/O)
	bs_map = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_PRIVATE, fd, 0);

This allows the file to be read in via page faults.
Then I get a suitable area from the kernel using another mmap which is
called on the PCI device :

//Get user space address of empty kernel memory of length bytes
arg = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_PRIVATE, htex_handle, 0);

Then I copy the data using memcpy and signal the PCI device to start
reading the data using a IOCTL

The problem I have is in the mmap implementation in the PCI driver :

static int htex_mmap(struct file * file, struct vm_area_struct * vma)
{
   vma->vm_flags |= VM_RESERVED;

   if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
		vma->vm_end - vma->vm_start,
		vma->vm_page_prot))
		return -EAGAIN;
	
   vma->vm_ops = &htex_vm_ops;
   htex_vma_open(vma);
	
   return 0;
}

When the driver gets the above call then I assume the kernel has
already allocated the required space and its details are in the vma
parameter. When I try to view the physical address of the virtual
address in the vma i use :

virt_to_phys(vma->vm_start)

But this gives me back the original address. A call like :
 DEBUG_MSG("htex_mmap called start:%lx, end:%lx, size:%lx, pfn:%lx, pa:%lx\n",
		vma->vm_start, vma->vm_end, vma->vm_end - vma->vm_start,
	   vma->vm_pgoff, virt_to_phys(vma->vm_start));

gives me

start:7f14b5afc000, end:7f14b5c0d000, size:111000, pfn:0, pa:f714b5afc000

I am able to get the page associated with vm_pgoff using :

struct page *pg = pfn_to_page(vma->vm_pgoff);
DEBUG_MSG("htex_mmap page: page address : %lx\n", page_address(pg));

which gives me something like :
 page address :: ffff880000000000

But this does not appear to be the correct physical address.

So how can I get the physical address of the space that the kernel
just allocated in response to the user's mmap() call on the device ?

I need the correct  physical address later to send to the FPGA as well.

Thanks
Abhi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ