Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ttm_bo_vm.c
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 /*
28  * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
29  */
30 
31 #define pr_fmt(fmt) "[TTM] " fmt
32 
33 #include <ttm/ttm_module.h>
34 #include <ttm/ttm_bo_driver.h>
35 #include <ttm/ttm_placement.h>
36 #include <linux/mm.h>
37 #include <linux/rbtree.h>
38 #include <linux/module.h>
39 #include <linux/uaccess.h>
40 
41 #define TTM_BO_VM_NUM_PREFAULT 16
42 
43 static struct ttm_buffer_object *ttm_bo_vm_lookup_rb(struct ttm_bo_device *bdev,
44  unsigned long page_start,
45  unsigned long num_pages)
46 {
47  struct rb_node *cur = bdev->addr_space_rb.rb_node;
48  unsigned long cur_offset;
49  struct ttm_buffer_object *bo;
50  struct ttm_buffer_object *best_bo = NULL;
51 
52  while (likely(cur != NULL)) {
53  bo = rb_entry(cur, struct ttm_buffer_object, vm_rb);
54  cur_offset = bo->vm_node->start;
55  if (page_start >= cur_offset) {
56  cur = cur->rb_right;
57  best_bo = bo;
58  if (page_start == cur_offset)
59  break;
60  } else
61  cur = cur->rb_left;
62  }
63 
64  if (unlikely(best_bo == NULL))
65  return NULL;
66 
67  if (unlikely((best_bo->vm_node->start + best_bo->num_pages) <
68  (page_start + num_pages)))
69  return NULL;
70 
71  return best_bo;
72 }
73 
74 static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
75 {
76  struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
77  vma->vm_private_data;
78  struct ttm_bo_device *bdev = bo->bdev;
79  unsigned long page_offset;
80  unsigned long page_last;
81  unsigned long pfn;
82  struct ttm_tt *ttm = NULL;
83  struct page *page;
84  int ret;
85  int i;
86  unsigned long address = (unsigned long)vmf->virtual_address;
87  int retval = VM_FAULT_NOPAGE;
88  struct ttm_mem_type_manager *man =
89  &bdev->man[bo->mem.mem_type];
90 
91  /*
92  * Work around locking order reversal in fault / nopfn
93  * between mmap_sem and bo_reserve: Perform a trylock operation
94  * for reserve, and if it fails, retry the fault after scheduling.
95  */
96 
97  ret = ttm_bo_reserve(bo, true, true, false, 0);
98  if (unlikely(ret != 0)) {
99  if (ret == -EBUSY)
100  set_need_resched();
101  return VM_FAULT_NOPAGE;
102  }
103 
104  if (bdev->driver->fault_reserve_notify) {
105  ret = bdev->driver->fault_reserve_notify(bo);
106  switch (ret) {
107  case 0:
108  break;
109  case -EBUSY:
110  set_need_resched();
111  case -ERESTARTSYS:
112  retval = VM_FAULT_NOPAGE;
113  goto out_unlock;
114  default:
115  retval = VM_FAULT_SIGBUS;
116  goto out_unlock;
117  }
118  }
119 
120  /*
121  * Wait for buffer data in transit, due to a pipelined
122  * move.
123  */
124 
125  spin_lock(&bdev->fence_lock);
127  ret = ttm_bo_wait(bo, false, true, false);
128  spin_unlock(&bdev->fence_lock);
129  if (unlikely(ret != 0)) {
130  retval = (ret != -ERESTARTSYS) ?
131  VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
132  goto out_unlock;
133  }
134  } else
135  spin_unlock(&bdev->fence_lock);
136 
137  ret = ttm_mem_io_lock(man, true);
138  if (unlikely(ret != 0)) {
139  retval = VM_FAULT_NOPAGE;
140  goto out_unlock;
141  }
143  if (unlikely(ret != 0)) {
144  retval = VM_FAULT_SIGBUS;
145  goto out_io_unlock;
146  }
147 
148  page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) +
149  bo->vm_node->start - vma->vm_pgoff;
150  page_last = ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) +
151  bo->vm_node->start - vma->vm_pgoff;
152 
153  if (unlikely(page_offset >= bo->num_pages)) {
154  retval = VM_FAULT_SIGBUS;
155  goto out_io_unlock;
156  }
157 
158  /*
159  * Strictly, we're not allowed to modify vma->vm_page_prot here,
160  * since the mmap_sem is only held in read mode. However, we
161  * modify only the caching bits of vma->vm_page_prot and
162  * consider those bits protected by
163  * the bo->mutex, as we should be the only writers.
164  * There shouldn't really be any readers of these bits except
165  * within vm_insert_mixed()? fork?
166  *
167  * TODO: Add a list of vmas to the bo, and change the
168  * vma->vm_page_prot when the object changes caching policy, with
169  * the correct locks held.
170  */
171  if (bo->mem.bus.is_iomem) {
172  vma->vm_page_prot = ttm_io_prot(bo->mem.placement,
173  vma->vm_page_prot);
174  } else {
175  ttm = bo->ttm;
176  vma->vm_page_prot = (bo->mem.placement & TTM_PL_FLAG_CACHED) ?
177  vm_get_page_prot(vma->vm_flags) :
178  ttm_io_prot(bo->mem.placement, vma->vm_page_prot);
179 
180  /* Allocate all page at once, most common usage */
181  if (ttm->bdev->driver->ttm_tt_populate(ttm)) {
182  retval = VM_FAULT_OOM;
183  goto out_io_unlock;
184  }
185  }
186 
187  /*
188  * Speculatively prefault a number of pages. Only error on
189  * first page.
190  */
191  for (i = 0; i < TTM_BO_VM_NUM_PREFAULT; ++i) {
192  if (bo->mem.bus.is_iomem)
193  pfn = ((bo->mem.bus.base + bo->mem.bus.offset) >> PAGE_SHIFT) + page_offset;
194  else {
195  page = ttm->pages[page_offset];
196  if (unlikely(!page && i == 0)) {
197  retval = VM_FAULT_OOM;
198  goto out_io_unlock;
199  } else if (unlikely(!page)) {
200  break;
201  }
202  pfn = page_to_pfn(page);
203  }
204 
205  ret = vm_insert_mixed(vma, address, pfn);
206  /*
207  * Somebody beat us to this PTE or prefaulting to
208  * an already populated PTE, or prefaulting error.
209  */
210 
211  if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
212  break;
213  else if (unlikely(ret != 0)) {
214  retval =
215  (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
216  goto out_io_unlock;
217  }
218 
219  address += PAGE_SIZE;
220  if (unlikely(++page_offset >= page_last))
221  break;
222  }
223 out_io_unlock:
224  ttm_mem_io_unlock(man);
225 out_unlock:
226  ttm_bo_unreserve(bo);
227  return retval;
228 }
229 
230 static void ttm_bo_vm_open(struct vm_area_struct *vma)
231 {
232  struct ttm_buffer_object *bo =
233  (struct ttm_buffer_object *)vma->vm_private_data;
234 
235  (void)ttm_bo_reference(bo);
236 }
237 
238 static void ttm_bo_vm_close(struct vm_area_struct *vma)
239 {
240  struct ttm_buffer_object *bo = (struct ttm_buffer_object *)vma->vm_private_data;
241 
242  ttm_bo_unref(&bo);
243  vma->vm_private_data = NULL;
244 }
245 
246 static const struct vm_operations_struct ttm_bo_vm_ops = {
247  .fault = ttm_bo_vm_fault,
248  .open = ttm_bo_vm_open,
249  .close = ttm_bo_vm_close
250 };
251 
252 int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
253  struct ttm_bo_device *bdev)
254 {
255  struct ttm_bo_driver *driver;
256  struct ttm_buffer_object *bo;
257  int ret;
258 
259  read_lock(&bdev->vm_lock);
260  bo = ttm_bo_vm_lookup_rb(bdev, vma->vm_pgoff,
261  (vma->vm_end - vma->vm_start) >> PAGE_SHIFT);
262  if (likely(bo != NULL))
263  ttm_bo_reference(bo);
264  read_unlock(&bdev->vm_lock);
265 
266  if (unlikely(bo == NULL)) {
267  pr_err("Could not find buffer object to map\n");
268  return -EINVAL;
269  }
270 
271  driver = bo->bdev->driver;
272  if (unlikely(!driver->verify_access)) {
273  ret = -EPERM;
274  goto out_unref;
275  }
276  ret = driver->verify_access(bo, filp);
277  if (unlikely(ret != 0))
278  goto out_unref;
279 
280  vma->vm_ops = &ttm_bo_vm_ops;
281 
282  /*
283  * Note: We're transferring the bo reference to
284  * vma->vm_private_data here.
285  */
286 
287  vma->vm_private_data = bo;
288  vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
289  return 0;
290 out_unref:
291  ttm_bo_unref(&bo);
292  return ret;
293 }
295 
296 int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo)
297 {
298  if (vma->vm_pgoff != 0)
299  return -EACCES;
300 
301  vma->vm_ops = &ttm_bo_vm_ops;
302  vma->vm_private_data = ttm_bo_reference(bo);
303  vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
304  return 0;
305 }
307 
308 
309 ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
310  const char __user *wbuf, char __user *rbuf, size_t count,
311  loff_t *f_pos, bool write)
312 {
313  struct ttm_buffer_object *bo;
314  struct ttm_bo_driver *driver;
315  struct ttm_bo_kmap_obj map;
316  unsigned long dev_offset = (*f_pos >> PAGE_SHIFT);
317  unsigned long kmap_offset;
318  unsigned long kmap_end;
319  unsigned long kmap_num;
320  size_t io_size;
321  unsigned int page_offset;
322  char *virtual;
323  int ret;
324  bool no_wait = false;
325  bool dummy;
326 
327  read_lock(&bdev->vm_lock);
328  bo = ttm_bo_vm_lookup_rb(bdev, dev_offset, 1);
329  if (likely(bo != NULL))
330  ttm_bo_reference(bo);
331  read_unlock(&bdev->vm_lock);
332 
333  if (unlikely(bo == NULL))
334  return -EFAULT;
335 
336  driver = bo->bdev->driver;
337  if (unlikely(!driver->verify_access)) {
338  ret = -EPERM;
339  goto out_unref;
340  }
341 
342  ret = driver->verify_access(bo, filp);
343  if (unlikely(ret != 0))
344  goto out_unref;
345 
346  kmap_offset = dev_offset - bo->vm_node->start;
347  if (unlikely(kmap_offset >= bo->num_pages)) {
348  ret = -EFBIG;
349  goto out_unref;
350  }
351 
352  page_offset = *f_pos & ~PAGE_MASK;
353  io_size = bo->num_pages - kmap_offset;
354  io_size = (io_size << PAGE_SHIFT) - page_offset;
355  if (count < io_size)
356  io_size = count;
357 
358  kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
359  kmap_num = kmap_end - kmap_offset + 1;
360 
361  ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
362 
363  switch (ret) {
364  case 0:
365  break;
366  case -EBUSY:
367  ret = -EAGAIN;
368  goto out_unref;
369  default:
370  goto out_unref;
371  }
372 
373  ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
374  if (unlikely(ret != 0)) {
375  ttm_bo_unreserve(bo);
376  goto out_unref;
377  }
378 
379  virtual = ttm_kmap_obj_virtual(&map, &dummy);
380  virtual += page_offset;
381 
382  if (write)
383  ret = copy_from_user(virtual, wbuf, io_size);
384  else
385  ret = copy_to_user(rbuf, virtual, io_size);
386 
387  ttm_bo_kunmap(&map);
388  ttm_bo_unreserve(bo);
389  ttm_bo_unref(&bo);
390 
391  if (unlikely(ret != 0))
392  return -EFBIG;
393 
394  *f_pos += io_size;
395 
396  return io_size;
397 out_unref:
398  ttm_bo_unref(&bo);
399  return ret;
400 }
401 
402 ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf,
403  char __user *rbuf, size_t count, loff_t *f_pos,
404  bool write)
405 {
406  struct ttm_bo_kmap_obj map;
407  unsigned long kmap_offset;
408  unsigned long kmap_end;
409  unsigned long kmap_num;
410  size_t io_size;
411  unsigned int page_offset;
412  char *virtual;
413  int ret;
414  bool no_wait = false;
415  bool dummy;
416 
417  kmap_offset = (*f_pos >> PAGE_SHIFT);
418  if (unlikely(kmap_offset >= bo->num_pages))
419  return -EFBIG;
420 
421  page_offset = *f_pos & ~PAGE_MASK;
422  io_size = bo->num_pages - kmap_offset;
423  io_size = (io_size << PAGE_SHIFT) - page_offset;
424  if (count < io_size)
425  io_size = count;
426 
427  kmap_end = (*f_pos + count - 1) >> PAGE_SHIFT;
428  kmap_num = kmap_end - kmap_offset + 1;
429 
430  ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
431 
432  switch (ret) {
433  case 0:
434  break;
435  case -EBUSY:
436  return -EAGAIN;
437  default:
438  return ret;
439  }
440 
441  ret = ttm_bo_kmap(bo, kmap_offset, kmap_num, &map);
442  if (unlikely(ret != 0)) {
443  ttm_bo_unreserve(bo);
444  return ret;
445  }
446 
447  virtual = ttm_kmap_obj_virtual(&map, &dummy);
448  virtual += page_offset;
449 
450  if (write)
451  ret = copy_from_user(virtual, wbuf, io_size);
452  else
453  ret = copy_to_user(rbuf, virtual, io_size);
454 
455  ttm_bo_kunmap(&map);
456  ttm_bo_unreserve(bo);
457  ttm_bo_unref(&bo);
458 
459  if (unlikely(ret != 0))
460  return ret;
461 
462  *f_pos += io_size;
463 
464  return io_size;
465 }