diff options
| -rw-r--r-- | drivers/char/drm/drm.h | 3 | ||||
| -rw-r--r-- | drivers/char/drm/drmP.h | 3 | ||||
| -rw-r--r-- | drivers/char/drm/drm_bufs.c | 10 | ||||
| -rw-r--r-- | drivers/char/drm/drm_vm.c | 16 |
4 files changed, 27 insertions, 5 deletions
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 3f28a1551621..8db9041e306c 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h | |||
| @@ -356,7 +356,8 @@ typedef struct drm_buf_desc { | |||
| 356 | _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ | 356 | _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ |
| 357 | _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ | 357 | _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ |
| 358 | _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ | 358 | _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ |
| 359 | _DRM_FB_BUFFER = 0x08 /**< Buffer is in frame buffer */ | 359 | _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ |
| 360 | _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ | ||
| 360 | } flags; | 361 | } flags; |
| 361 | unsigned long agp_start; /**< | 362 | unsigned long agp_start; /**< |
| 362 | * Start address of where the AGP buffers are | 363 | * Start address of where the AGP buffers are |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 2f18329c5eb8..0bbb04f2390f 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
| @@ -431,7 +431,8 @@ typedef struct drm_device_dma { | |||
| 431 | enum { | 431 | enum { |
| 432 | _DRM_DMA_USE_AGP = 0x01, | 432 | _DRM_DMA_USE_AGP = 0x01, |
| 433 | _DRM_DMA_USE_SG = 0x02, | 433 | _DRM_DMA_USE_SG = 0x02, |
| 434 | _DRM_DMA_USE_FB = 0x04 | 434 | _DRM_DMA_USE_FB = 0x04, |
| 435 | _DRM_DMA_USE_PCI_RO = 0x08 | ||
| 435 | } flags; | 436 | } flags; |
| 436 | 437 | ||
| 437 | } drm_device_dma_t; | 438 | } drm_device_dma_t; |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 6eafff13dab6..9f65f5697ba8 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
| @@ -887,6 +887,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 887 | request->count = entry->buf_count; | 887 | request->count = entry->buf_count; |
| 888 | request->size = size; | 888 | request->size = size; |
| 889 | 889 | ||
| 890 | if (request->flags & _DRM_PCI_BUFFER_RO) | ||
| 891 | dma->flags = _DRM_DMA_USE_PCI_RO; | ||
| 892 | |||
| 890 | atomic_dec(&dev->buf_alloc); | 893 | atomic_dec(&dev->buf_alloc); |
| 891 | return 0; | 894 | return 0; |
| 892 | 895 | ||
| @@ -1471,9 +1474,10 @@ int drm_freebufs(struct inode *inode, struct file *filp, | |||
| 1471 | * \param arg pointer to a drm_buf_map structure. | 1474 | * \param arg pointer to a drm_buf_map structure. |
| 1472 | * \return zero on success or a negative number on failure. | 1475 | * \return zero on success or a negative number on failure. |
| 1473 | * | 1476 | * |
| 1474 | * Maps the AGP or SG buffer region with do_mmap(), and copies information | 1477 | * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information |
| 1475 | * about each buffer into user space. The PCI buffers are already mapped on the | 1478 | * about each buffer into user space. For PCI buffers, it calls do_mmap() with |
| 1476 | * addbufs_pci() call. | 1479 | * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls |
| 1480 | * drm_mmap_dma(). | ||
| 1477 | */ | 1481 | */ |
| 1478 | int drm_mapbufs(struct inode *inode, struct file *filp, | 1482 | int drm_mapbufs(struct inode *inode, struct file *filp, |
| 1479 | unsigned int cmd, unsigned long arg) | 1483 | unsigned int cmd, unsigned long arg) |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index b40ae438f531..74686e9a2d34 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
| @@ -473,6 +473,22 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) | |||
| 473 | } | 473 | } |
| 474 | unlock_kernel(); | 474 | unlock_kernel(); |
| 475 | 475 | ||
| 476 | if (!capable(CAP_SYS_ADMIN) && | ||
| 477 | (dma->flags & _DRM_DMA_USE_PCI_RO)) { | ||
| 478 | vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE); | ||
| 479 | #if defined(__i386__) || defined(__x86_64__) | ||
| 480 | pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW; | ||
| 481 | #else | ||
| 482 | /* Ye gads this is ugly. With more thought | ||
| 483 | we could move this up higher and use | ||
| 484 | `protection_map' instead. */ | ||
| 485 | vma->vm_page_prot = | ||
| 486 | __pgprot(pte_val | ||
| 487 | (pte_wrprotect | ||
| 488 | (__pte(pgprot_val(vma->vm_page_prot))))); | ||
| 489 | #endif | ||
| 490 | } | ||
| 491 | |||
| 476 | vma->vm_ops = &drm_vm_dma_ops; | 492 | vma->vm_ops = &drm_vm_dma_ops; |
| 477 | 493 | ||
| 478 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ | 494 | vma->vm_flags |= VM_RESERVED; /* Don't swap */ |
