aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/include/linux
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2017-04-06 09:34:54 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2017-04-06 09:34:54 +0000
commit1ea4c85781e9404e78b9444f27cf4f8ed3915649 (patch)
tree138c3bb83d0e8e006c09e00b5f341add3f65a7e6 /sys/compat/linuxkpi/common/include/linux
parente54b103e700fe6c38316cecd39957561197379a6 (diff)
downloadsrc-1ea4c85781e9404e78b9444f27cf4f8ed3915649.tar.gz
src-1ea4c85781e9404e78b9444f27cf4f8ed3915649.zip
Implement proper support for memory map operations in the LinuxKPI,
like open, close and fault using the character device pager. Some notes about the implementation: 1) Linux drivers set the vm_ops and vm_private_data fields during a mmap() call to indicate that the driver wants to use the LinuxKPI VM operations. Else these operations are not used. 2) The vm_private_data pointer is associated with a VM area structure and inserted into an internal LinuxKPI list. If the vm_private_data pointer already exists, the existing VM area structure is used instead of the allocated one which gets freed. 3) The LinuxKPI's vm_private_data pointer is used as the callback handle for the FreeBSD VM object. The VM subsystem in FreeBSD has a similar list to identify equal handles and will only call the character device pager's close function once. 4) All LinuxKPI VM operations are serialized through the mmap_sem sempaphore, which is per procedure, which prevents simultaneous access to the shared VM area structure when receiving page faults. Obtained from: kmacy @ MFC after: 1 week Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=316562
Diffstat (limited to 'sys/compat/linuxkpi/common/include/linux')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/mm.h26
-rw-r--r--sys/compat/linuxkpi/common/include/linux/page.h22
2 files changed, 42 insertions, 6 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h
index f652e3be325e..67ac02daff76 100644
--- a/sys/compat/linuxkpi/common/include/linux/mm.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm.h
@@ -38,6 +38,7 @@
#include <linux/kernel.h>
#include <linux/mm_types.h>
#include <linux/pfn.h>
+#include <linux/list.h>
#include <asm/pgtable.h>
@@ -89,12 +90,25 @@ CTASSERT((VM_PROT_ALL & -(1 << 8)) == 0);
typedef int (*pte_fn_t)(pte_t *, pgtable_t, unsigned long addr, void *data);
struct vm_area_struct {
- vm_offset_t vm_start;
- 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;
+ vm_offset_t vm_start;
+ vm_offset_t vm_end;
+ vm_offset_t vm_pgoff;
+ pgprot_t vm_page_prot;
+ unsigned long vm_flags;
+ struct mm_struct *vm_mm;
+ void *vm_private_data;
+ const struct vm_operations_struct *vm_ops;
+ struct linux_file *vm_file;
+
+ /* internal operation */
+ vm_paddr_t vm_pfn; /* PFN for memory map */
+ vm_size_t vm_len; /* length for memory map */
+ vm_pindex_t vm_pfn_first;
+ int vm_pfn_count;
+ int *vm_pfn_pcount;
+ vm_object_t vm_obj;
+ vm_map_t vm_cached_map;
+ TAILQ_ENTRY(vm_area_struct) vm_entry;
};
struct vm_fault {
diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h
index 7e84e0440451..a40308e44dee 100644
--- a/sys/compat/linuxkpi/common/include/linux/page.h
+++ b/sys/compat/linuxkpi/common/include/linux/page.h
@@ -47,6 +47,28 @@ typedef unsigned long pgprot_t;
#define page vm_page
+#define LINUXKPI_PROT_VALID (1 << 4)
+#define LINUXKPI_CACHE_MODE_SHIFT 3
+
+static inline pgprot_t
+cachemode2protval(vm_memattr_t attr)
+{
+ return ((attr | LINUXKPI_PROT_VALID) << LINUXKPI_CACHE_MODE_SHIFT);
+}
+
+static inline vm_memattr_t
+pgprot2cachemode(pgprot_t prot)
+{
+ int val;
+
+ val = prot >> LINUXKPI_CACHE_MODE_SHIFT;
+
+ if (val & LINUXKPI_PROT_VALID)
+ return (val & ~LINUXKPI_PROT_VALID);
+ else
+ return (VM_MEMATTR_DEFAULT);
+}
+
#define virt_to_page(x) PHYS_TO_VM_PAGE(vtophys((x)))
#define page_to_pfn(pp) (VM_PAGE_TO_PHYS((pp)) >> PAGE_SHIFT)
#define pfn_to_page(pfn) (PHYS_TO_VM_PAGE((pfn) << PAGE_SHIFT))