diff options
| -rw-r--r-- | drivers/char/hpet.c | 14 | ||||
| -rw-r--r-- | drivers/mtd/mtdchar.c | 59 | ||||
| -rw-r--r-- | drivers/video/fbmem.c | 39 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 12 |
4 files changed, 19 insertions, 105 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index e3f9a99b8522..d784650d14f0 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
| @@ -373,26 +373,14 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 373 | struct hpet_dev *devp; | 373 | struct hpet_dev *devp; |
| 374 | unsigned long addr; | 374 | unsigned long addr; |
| 375 | 375 | ||
| 376 | if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) | ||
| 377 | return -EINVAL; | ||
| 378 | |||
| 379 | devp = file->private_data; | 376 | devp = file->private_data; |
| 380 | addr = devp->hd_hpets->hp_hpet_phys; | 377 | addr = devp->hd_hpets->hp_hpet_phys; |
| 381 | 378 | ||
| 382 | if (addr & (PAGE_SIZE - 1)) | 379 | if (addr & (PAGE_SIZE - 1)) |
| 383 | return -ENOSYS; | 380 | return -ENOSYS; |
| 384 | 381 | ||
| 385 | vma->vm_flags |= VM_IO; | ||
| 386 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 382 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 387 | 383 | return vm_iomap_memory(vma, addr, PAGE_SIZE); | |
| 388 | if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, | ||
| 389 | PAGE_SIZE, vma->vm_page_prot)) { | ||
| 390 | printk(KERN_ERR "%s: io_remap_pfn_range failed\n", | ||
| 391 | __func__); | ||
| 392 | return -EAGAIN; | ||
| 393 | } | ||
| 394 | |||
| 395 | return 0; | ||
| 396 | #else | 384 | #else |
| 397 | return -ENOSYS; | 385 | return -ENOSYS; |
| 398 | #endif | 386 | #endif |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 92ab30ab00dc..dc571ebc1aa0 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
| @@ -1123,33 +1123,6 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file, | |||
| 1123 | } | 1123 | } |
| 1124 | #endif | 1124 | #endif |
| 1125 | 1125 | ||
| 1126 | static inline unsigned long get_vm_size(struct vm_area_struct *vma) | ||
| 1127 | { | ||
| 1128 | return vma->vm_end - vma->vm_start; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | static inline resource_size_t get_vm_offset(struct vm_area_struct *vma) | ||
| 1132 | { | ||
| 1133 | return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT; | ||
| 1134 | } | ||
| 1135 | |||
| 1136 | /* | ||
| 1137 | * Set a new vm offset. | ||
| 1138 | * | ||
| 1139 | * Verify that the incoming offset really works as a page offset, | ||
| 1140 | * and that the offset and size fit in a resource_size_t. | ||
| 1141 | */ | ||
| 1142 | static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off) | ||
| 1143 | { | ||
| 1144 | pgoff_t pgoff = off >> PAGE_SHIFT; | ||
| 1145 | if (off != (resource_size_t) pgoff << PAGE_SHIFT) | ||
| 1146 | return -EINVAL; | ||
| 1147 | if (off + get_vm_size(vma) - 1 < off) | ||
| 1148 | return -EINVAL; | ||
| 1149 | vma->vm_pgoff = pgoff; | ||
| 1150 | return 0; | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | /* | 1126 | /* |
| 1154 | * set up a mapping for shared memory segments | 1127 | * set up a mapping for shared memory segments |
| 1155 | */ | 1128 | */ |
| @@ -1159,45 +1132,17 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1159 | struct mtd_file_info *mfi = file->private_data; | 1132 | struct mtd_file_info *mfi = file->private_data; |
| 1160 | struct mtd_info *mtd = mfi->mtd; | 1133 | struct mtd_info *mtd = mfi->mtd; |
| 1161 | struct map_info *map = mtd->priv; | 1134 | struct map_info *map = mtd->priv; |
| 1162 | resource_size_t start, off; | ||
| 1163 | unsigned long len, vma_len; | ||
| 1164 | 1135 | ||
| 1165 | /* This is broken because it assumes the MTD device is map-based | 1136 | /* This is broken because it assumes the MTD device is map-based |
| 1166 | and that mtd->priv is a valid struct map_info. It should be | 1137 | and that mtd->priv is a valid struct map_info. It should be |
| 1167 | replaced with something that uses the mtd_get_unmapped_area() | 1138 | replaced with something that uses the mtd_get_unmapped_area() |
| 1168 | operation properly. */ | 1139 | operation properly. */ |
| 1169 | if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { | 1140 | if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { |
| 1170 | off = get_vm_offset(vma); | ||
| 1171 | start = map->phys; | ||
| 1172 | len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); | ||
| 1173 | start &= PAGE_MASK; | ||
| 1174 | vma_len = get_vm_size(vma); | ||
| 1175 | |||
| 1176 | /* Overflow in off+len? */ | ||
| 1177 | if (vma_len + off < off) | ||
| 1178 | return -EINVAL; | ||
| 1179 | /* Does it fit in the mapping? */ | ||
| 1180 | if (vma_len + off > len) | ||
| 1181 | return -EINVAL; | ||
| 1182 | |||
| 1183 | off += start; | ||
| 1184 | /* Did that overflow? */ | ||
| 1185 | if (off < start) | ||
| 1186 | return -EINVAL; | ||
| 1187 | if (set_vm_offset(vma, off) < 0) | ||
| 1188 | return -EINVAL; | ||
| 1189 | vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; | ||
| 1190 | |||
| 1191 | #ifdef pgprot_noncached | 1141 | #ifdef pgprot_noncached |
| 1192 | if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) | 1142 | if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory)) |
| 1193 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 1143 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 1194 | #endif | 1144 | #endif |
| 1195 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1145 | return vm_iomap_memory(vma, map->phys, map->size); |
| 1196 | vma->vm_end - vma->vm_start, | ||
| 1197 | vma->vm_page_prot)) | ||
| 1198 | return -EAGAIN; | ||
| 1199 | |||
| 1200 | return 0; | ||
| 1201 | } | 1146 | } |
| 1202 | return -ENOSYS; | 1147 | return -ENOSYS; |
| 1203 | #else | 1148 | #else |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 7c254084b6a0..86291dcd964a 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
| @@ -1373,15 +1373,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
| 1373 | { | 1373 | { |
| 1374 | struct fb_info *info = file_fb_info(file); | 1374 | struct fb_info *info = file_fb_info(file); |
| 1375 | struct fb_ops *fb; | 1375 | struct fb_ops *fb; |
| 1376 | unsigned long off; | 1376 | unsigned long mmio_pgoff; |
| 1377 | unsigned long start; | 1377 | unsigned long start; |
| 1378 | u32 len; | 1378 | u32 len; |
| 1379 | 1379 | ||
| 1380 | if (!info) | 1380 | if (!info) |
| 1381 | return -ENODEV; | 1381 | return -ENODEV; |
| 1382 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) | ||
| 1383 | return -EINVAL; | ||
| 1384 | off = vma->vm_pgoff << PAGE_SHIFT; | ||
| 1385 | fb = info->fbops; | 1382 | fb = info->fbops; |
| 1386 | if (!fb) | 1383 | if (!fb) |
| 1387 | return -ENODEV; | 1384 | return -ENODEV; |
| @@ -1393,32 +1390,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
| 1393 | return res; | 1390 | return res; |
| 1394 | } | 1391 | } |
| 1395 | 1392 | ||
| 1396 | /* frame buffer memory */ | 1393 | /* |
| 1394 | * Ugh. This can be either the frame buffer mapping, or | ||
| 1395 | * if pgoff points past it, the mmio mapping. | ||
| 1396 | */ | ||
| 1397 | start = info->fix.smem_start; | 1397 | start = info->fix.smem_start; |
| 1398 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); | 1398 | len = info->fix.smem_len; |
| 1399 | if (off >= len) { | 1399 | mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; |
| 1400 | /* memory mapped io */ | 1400 | if (vma->vm_pgoff >= mmio_pgoff) { |
| 1401 | off -= len; | 1401 | vma->vm_pgoff -= mmio_pgoff; |
| 1402 | if (info->var.accel_flags) { | ||
| 1403 | mutex_unlock(&info->mm_lock); | ||
| 1404 | return -EINVAL; | ||
| 1405 | } | ||
| 1406 | start = info->fix.mmio_start; | 1402 | start = info->fix.mmio_start; |
| 1407 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1403 | len = info->fix.mmio_len; |
| 1408 | } | 1404 | } |
| 1409 | mutex_unlock(&info->mm_lock); | 1405 | mutex_unlock(&info->mm_lock); |
| 1410 | start &= PAGE_MASK; | 1406 | |
| 1411 | if ((vma->vm_end - vma->vm_start + off) > len) | ||
| 1412 | return -EINVAL; | ||
| 1413 | off += start; | ||
| 1414 | vma->vm_pgoff = off >> PAGE_SHIFT; | ||
| 1415 | /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/ | ||
| 1416 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 1407 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
| 1417 | fb_pgprotect(file, vma, off); | 1408 | fb_pgprotect(file, vma, start); |
| 1418 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1409 | |
| 1419 | vma->vm_end - vma->vm_start, vma->vm_page_prot)) | 1410 | return vm_iomap_memory(vma, start, len); |
| 1420 | return -EAGAIN; | ||
| 1421 | return 0; | ||
| 1422 | } | 1411 | } |
| 1423 | 1412 | ||
| 1424 | static int | 1413 | static int |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 71ae86ca64ac..eb560fa32321 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -3222,18 +3222,10 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | |||
| 3222 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3222 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
| 3223 | struct vm_area_struct *area) | 3223 | struct vm_area_struct *area) |
| 3224 | { | 3224 | { |
| 3225 | long size; | 3225 | struct snd_pcm_runtime *runtime = substream->runtime;; |
| 3226 | unsigned long offset; | ||
| 3227 | 3226 | ||
| 3228 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3227 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
| 3229 | area->vm_flags |= VM_IO; | 3228 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); |
| 3230 | size = area->vm_end - area->vm_start; | ||
| 3231 | offset = area->vm_pgoff << PAGE_SHIFT; | ||
| 3232 | if (io_remap_pfn_range(area, area->vm_start, | ||
| 3233 | (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, | ||
| 3234 | size, area->vm_page_prot)) | ||
| 3235 | return -EAGAIN; | ||
| 3236 | return 0; | ||
| 3237 | } | 3229 | } |
| 3238 | 3230 | ||
| 3239 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); | 3231 | EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); |
