|
@@ -1534,6 +1534,12 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|
struct drm_gem_object *obj;
|
|
struct drm_gem_object *obj;
|
|
unsigned long addr;
|
|
unsigned long addr;
|
|
|
|
|
|
|
|
+ if (args->flags & ~(I915_MMAP_WC))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ if (args->flags & I915_MMAP_WC && !cpu_has_pat)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
obj = drm_gem_object_lookup(dev, file, args->handle);
|
|
obj = drm_gem_object_lookup(dev, file, args->handle);
|
|
if (obj == NULL)
|
|
if (obj == NULL)
|
|
return -ENOENT;
|
|
return -ENOENT;
|
|
@@ -1549,6 +1555,19 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|
addr = vm_mmap(obj->filp, 0, args->size,
|
|
addr = vm_mmap(obj->filp, 0, args->size,
|
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
args->offset);
|
|
args->offset);
|
|
|
|
+ if (args->flags & I915_MMAP_WC) {
|
|
|
|
+ struct mm_struct *mm = current->mm;
|
|
|
|
+ struct vm_area_struct *vma;
|
|
|
|
+
|
|
|
|
+ down_write(&mm->mmap_sem);
|
|
|
|
+ vma = find_vma(mm, addr);
|
|
|
|
+ if (vma)
|
|
|
|
+ vma->vm_page_prot =
|
|
|
|
+ pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
|
|
|
|
+ else
|
|
|
|
+ addr = -ENOMEM;
|
|
|
|
+ up_write(&mm->mmap_sem);
|
|
|
|
+ }
|
|
drm_gem_object_unreference_unlocked(obj);
|
|
drm_gem_object_unreference_unlocked(obj);
|
|
if (IS_ERR((void *)addr))
|
|
if (IS_ERR((void *)addr))
|
|
return addr;
|
|
return addr;
|