@@ -37,6 +37,17 @@ struct remap_pfn {
3737 resource_size_t iobase ;
3838};
3939
40+ static int remap_pfn (pte_t * pte , unsigned long addr , void * data )
41+ {
42+ struct remap_pfn * r = data ;
43+
44+ /* Special PTE are not associated with any struct page */
45+ set_pte_at (r -> mm , addr , pte , pte_mkspecial (pfn_pte (r -> pfn , r -> prot )));
46+ r -> pfn ++ ;
47+
48+ return 0 ;
49+ }
50+
4051#define use_dma (io ) ((io) != -1)
4152
4253static inline unsigned long sgt_pfn (const struct remap_pfn * r )
@@ -66,7 +77,40 @@ static int remap_sg(pte_t *pte, unsigned long addr, void *data)
6677 return 0 ;
6778}
6879
80+ /**
81+ * remap_io_mapping - remap an IO mapping to userspace
82+ * @vma: user vma to map to
83+ * @addr: target user address to start at
84+ * @pfn: physical address of kernel memory
85+ * @size: size of map area
86+ * @iomap: the source io_mapping
87+ *
88+ * Note: this is only safe if the mm semaphore is held when called.
89+ */
90+ int remap_io_mapping (struct vm_area_struct * vma ,
91+ unsigned long addr , unsigned long pfn , unsigned long size ,
92+ struct io_mapping * iomap )
93+ {
94+ struct remap_pfn r ;
95+ int err ;
96+
6997#define EXPECTED_FLAGS (VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP)
98+ GEM_BUG_ON ((vma -> vm_flags & EXPECTED_FLAGS ) != EXPECTED_FLAGS );
99+
100+ /* We rely on prevalidation of the io-mapping to skip track_pfn(). */
101+ r .mm = vma -> vm_mm ;
102+ r .pfn = pfn ;
103+ r .prot = __pgprot ((pgprot_val (iomap -> prot ) & _PAGE_CACHE_MASK ) |
104+ (pgprot_val (vma -> vm_page_prot ) & ~_PAGE_CACHE_MASK ));
105+
106+ err = apply_to_page_range (r .mm , addr , size , remap_pfn , & r );
107+ if (unlikely (err )) {
108+ zap_vma_ptes (vma , addr , (r .pfn - pfn ) << PAGE_SHIFT );
109+ return err ;
110+ }
111+
112+ return 0 ;
113+ }
70114
71115/**
72116 * remap_io_sg - remap an IO mapping to userspace
0 commit comments