svn commit: r287637 - in stable: 10/sys/ofed/include/linux 9/sys/ofed/include/linux

John Baldwin jhb at FreeBSD.org
Fri Sep 11 00:20:17 UTC 2015


Author: jhb
Date: Fri Sep 11 00:20:15 2015
New Revision: 287637
URL: https://svnweb.freebsd.org/changeset/base/287637

Log:
  MFC 287440:
  Currently the Linux character device mmap handling only supports mmap
  operations that map a single page that has an associated vm_page_t.
  This does not permit mapping larger regions (such as a PCI memory
  BAR) and it does not permit mapping addresses beyond the top of RAM
  (such as a 64-bit BAR located above the top of RAM).
  
  Instead of using a single OBJT_DEVICE object and passing the physaddr via
  the offset as a hack, create a new sglist and OBJT_SG object for each
  mmap request. The requested memory attribute is applied to the object
  thus affecting all pages mapped by the request.
  
  Sponsored by:	Chelsio

Modified:
  stable/9/sys/ofed/include/linux/linux_compat.c
  stable/9/sys/ofed/include/linux/mm.h
Directory Properties:
  stable/9/sys/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/10/sys/ofed/include/linux/linux_compat.c
  stable/10/sys/ofed/include/linux/mm.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/9/sys/ofed/include/linux/linux_compat.c
==============================================================================
--- stable/9/sys/ofed/include/linux/linux_compat.c	Fri Sep 11 00:19:49 2015	(r287636)
+++ stable/9/sys/ofed/include/linux/linux_compat.c	Fri Sep 11 00:20:15 2015	(r287637)
@@ -33,6 +33,7 @@
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/proc.h>
+#include <sys/sglist.h>
 #include <sys/sleepqueue.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -413,16 +414,6 @@ linux_dev_poll(struct cdev *dev, int eve
 }
 
 static int
-linux_dev_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
-    int nprot, vm_memattr_t *memattr)
-{
-
-	/* XXX memattr not honored. */
-	*paddr = offset;
-	return (0);
-}
-
-static int
 linux_dev_mmap_single(struct cdev *dev, vm_ooffset_t *offset,
     vm_size_t size, struct vm_object **object, int nprot)
 {
@@ -430,36 +421,41 @@ linux_dev_mmap_single(struct cdev *dev, 
 	struct linux_file *filp;
 	struct file *file;
 	struct vm_area_struct vma;
-	vm_paddr_t paddr;
-	vm_page_t m;
 	int error;
 
 	file = curthread->td_fpop;
 	ldev = dev->si_drv1;
 	if (ldev == NULL)
 		return (ENODEV);
-	if (size != PAGE_SIZE)
-		return (EINVAL);
 	if ((error = devfs_get_cdevpriv((void **)&filp)) != 0)
 		return (error);
 	filp->f_flags = file->f_flag;
 	vma.vm_start = 0;
-	vma.vm_end = PAGE_SIZE;
+	vma.vm_end = size;
 	vma.vm_pgoff = *offset / PAGE_SIZE;
 	vma.vm_pfn = 0;
 	vma.vm_page_prot = 0;
 	if (filp->f_op->mmap) {
 		error = -filp->f_op->mmap(filp, &vma);
 		if (error == 0) {
-			paddr = (vm_paddr_t)vma.vm_pfn << PAGE_SHIFT;
-			*offset = paddr;
-			m = PHYS_TO_VM_PAGE(paddr);
-			*object = vm_pager_allocate(OBJT_DEVICE, dev,
-			    PAGE_SIZE, nprot, *offset, curthread->td_ucred);
-		        if (*object == NULL)
-               			 return (EINVAL);
-			if (vma.vm_page_prot != VM_MEMATTR_DEFAULT)
-				pmap_page_set_memattr(m, vma.vm_page_prot);
+			struct sglist *sg;
+
+			sg = sglist_alloc(1, M_WAITOK);
+			sglist_append_phys(sg,
+			    (vm_paddr_t)vma.vm_pfn << PAGE_SHIFT, vma.vm_len);
+			*object = vm_pager_allocate(OBJT_SG, sg, vma.vm_len,
+			    nprot, 0, curthread->td_ucred);
+		        if (*object == NULL) {
+				sglist_free(sg);
+				return (EINVAL);
+			}
+			*offset = 0;
+			if (vma.vm_page_prot != VM_MEMATTR_DEFAULT) {
+				VM_OBJECT_LOCK(*object);
+				vm_object_set_memattr(*object,
+				    vma.vm_page_prot);
+				VM_OBJECT_UNLOCK(*object);
+			}
 		}
 	} else
 		error = ENODEV;
@@ -476,7 +472,6 @@ struct cdevsw linuxcdevsw = {
 	.d_write = linux_dev_write,
 	.d_ioctl = linux_dev_ioctl,
 	.d_mmap_single = linux_dev_mmap_single,
-	.d_mmap = linux_dev_mmap,
 	.d_poll = linux_dev_poll,
 };
 

Modified: stable/9/sys/ofed/include/linux/mm.h
==============================================================================
--- stable/9/sys/ofed/include/linux/mm.h	Fri Sep 11 00:19:49 2015	(r287636)
+++ stable/9/sys/ofed/include/linux/mm.h	Fri Sep 11 00:20:15 2015	(r287637)
@@ -40,6 +40,7 @@ struct vm_area_struct {
 	vm_offset_t	vm_end;
 	vm_offset_t	vm_pgoff;
 	vm_paddr_t	vm_pfn;		/* PFN For mmap. */
+	vm_size_t	vm_len;		/* length for mmap. */
 	vm_memattr_t	vm_page_prot;
 };
 
@@ -78,6 +79,7 @@ io_remap_pfn_range(struct vm_area_struct
 {
 	vma->vm_page_prot = prot;
 	vma->vm_pfn = pfn;
+	vma->vm_len = size;
 
 	return (0);
 }


More information about the svn-src-all mailing list