linux-4.4.1/do_mmap()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#u26fa5e1]
#backlinks
*説明 [#s33392ff]
-パス: 複数あり
--CONFIG_MMU 有効: [[linux-4.4.1/mm/mmap.c]]
--CONFIG_MMU 無効: [[linux-4.4.1/mm/nommu.c]]
-FIXME: これは何?
--説明
**引数 [#md56d548]
-struct file *file
--
--[[linux-4.4.1/file]]
-unsigned long addr
--
-unsigned long len
--
-unsigned long prot
--
-unsigned long flags
--
-vm_flags_t vm_flags
-
--[[linux-4.4.1/vm_flags_t]]
-unsigned long pgoff
--
-unsigned long *populate
--
**返り値 [#a7f2941d]
-unsigned long
--
**参考 [#dd70ae03]
*実装 [#b3e8556d]
**CONFIG_MMU 有効: mm/mmap.c [#r7ba5410]
/*
* The caller must hold down_write(¤t->mm->mmap_se...
*/
unsigned long do_mmap(struct file *file, unsigned long a...
unsigned long len, unsigned long...
unsigned long flags, vm_flags_t ...
unsigned long pgoff, unsigned lo...
{
struct mm_struct *mm = current->mm;
-
--[[linux-4.4.1/mm_struct]]
--[[linux-4.4.1/current(global)]]
*populate = 0;
if (!len)
return -EINVAL;
/*
* Does the application expect PROT_READ to impl...
*
* (the exception is when the underlying filesys...
* mounted, in which case we dont add PROT_EXEC.)
*/
if ((prot & PROT_READ) && (current->personality ...
if (!(file && path_noexec(&file->f_path)))
prot |= PROT_EXEC;
-
--[[linux-4.4.1/PROT_READ]]
--[[linux-4.4.1/path_noexec()]]
--[[linux-4.4.1/PROT_EXEC]]
if (!(flags & MAP_FIXED))
addr = round_hint_to_min(addr);
-
--[[linux-4.4.1/MAP_FIXED]]
--[[linux-4.4.1/round_hint_to_min()]]
/* Careful about overflows.. */
len = PAGE_ALIGN(len);
if (!len)
return -ENOMEM;
-
--[[linux-4.4.1/PAGE_ALIGN()]]
/* offset overflow? */
if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
return -EOVERFLOW;
/* Too many mappings? */
if (mm->map_count > sysctl_max_map_count)
return -ENOMEM;
/* Obtain the address to map to. we verify (or s...
* that it represents a valid section of the add...
*/
addr = get_unmapped_area(file, addr, len, pgoff,...
if (offset_in_page(addr))
return addr;
-
--[[linux-4.4.1/get_unmmapped_area()]]
--[[linux-4.4.1/offset_in_page()]]
/* Do simple checking here so the lower-level ro...
* to. we assume access permissions have been ha...
* of the memory object, so we don't do any here.
*/
vm_flags |= calc_vm_prot_bits(prot) | calc_vm_fl...
mm->def_flags | VM_MAYREAD | VM_...
-
--[[linux-4.4.1/calc_vm_prot_bits()]]
--[[linux-4.4.1/calc_vm_flag_bis()]]
--[[linux-4.4.1/VM_MAYREAD]]
--[[linux-4.4.1/VM_MAYWRITE]]
--[[linux-4.4.1/VM_MAY_EXEC]]
if (flags & MAP_LOCKED)
if (!can_do_mlock())
return -EPERM;
-
--[[linux-4.4.1/MAP_LOCKED]]
--[[linux-4.4.1/can_do_mlock()]]
if (mlock_future_check(mm, vm_flags, len))
return -EAGAIN;
-
--[[linux-4.4.1/mlock_future_check()]]
if (file) {
struct inode *inode = file_inode(file);
-
--[[linux-4.4.1/inode]]
--[[linux-4.4.1/file_inode()]]
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if ((prot&PROT_WRITE) && !(file-...
return -EACCES;
/*
* Make sure we don't allow writ...
* file..
*/
if (IS_APPEND(inode) && (file->f...
return -EACCES;
-
--[[linux-4.4.1/IS_APPEND()]]
/*
* Make sure there are no mandat...
*/
if (locks_verify_locked(file))
return -EAGAIN;
-
--[[linux-4.4.1/locks_verify_locked()]]
vm_flags |= VM_SHARED | VM_MAYSH...
if (!(file->f_mode & FMODE_WRITE))
vm_flags &= ~(VM_MAYWRIT...
/* fall through */
case MAP_PRIVATE:
if (!(file->f_mode & FMODE_READ))
return -EACCES;
if (path_noexec(&file->f_path)) {
if (vm_flags & VM_EXEC)
return -EPERM;
vm_flags &= ~VM_MAYEXEC;
}
if (!file->f_op->mmap)
return -ENODEV;
if (vm_flags & (VM_GROWSDOWN|VM_...
return -EINVAL;
break;
default:
return -EINVAL;
}
} else {
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if (vm_flags & (VM_GROWSDOWN|VM_...
return -EINVAL;
/*
* Ignore pgoff.
*/
pgoff = 0;
vm_flags |= VM_SHARED | VM_MAYSH...
break;
case MAP_PRIVATE:
/*
* Set pgoff according to addr f...
*/
pgoff = addr >> PAGE_SHIFT;
break;
default:
return -EINVAL;
}
}
/*
* Set 'VM_NORESERVE' if we should not account f...
* memory use of this mapping.
*/
if (flags & MAP_NORESERVE) {
/* We honor MAP_NORESERVE if allowed to ...
if (sysctl_overcommit_memory != OVERCOMM...
vm_flags |= VM_NORESERVE;
-
--[[linux-4.4.1/sysctl_overcommit_memory(global)]]
--[[linux-4.4.1/OVERCOMMIT_NEVER]]
--[[linux-4.4.1/VM_NORESERVE]]
/* hugetlb applies strict overcommit unl...
if (file && is_file_hugepages(file))
vm_flags |= VM_NORESERVE;
}
addr = mmap_region(file, addr, len, vm_flags, pg...
-
--[[linux-4.4.1/mmap_region()]]
if (!IS_ERR_VALUE(addr) &&
((vm_flags & VM_LOCKED) ||
(flags & (MAP_POPULATE | MAP_NONBLOCK)) == ...
*populate = len;
return addr;
}
**CONFIG_MMU 無効: mm/nommu.c [#n2c5c527]
/*
* handle mapping creation for uClinux
*/
unsigned long do_mmap(struct file *file,
unsigned long addr,
unsigned long len,
unsigned long prot,
unsigned long flags,
vm_flags_t vm_flags,
unsigned long pgoff,
unsigned long *populate)
{
struct vm_area_struct *vma;
struct vm_region *region;
struct rb_node *rb;
unsigned long capabilities, result;
int ret;
-
--[[linux-4.4.1/vm_area_struct]]
--[[linux-4.4.1/vm_region]]
--[[linux-4.4.1/rb_node]]
*populate = 0;
/* decide whether we should attempt the mapping,...
* mapping */
ret = validate_mmap_request(file, addr, len, pro...
&capabilities);
if (ret < 0)
return ret;
-
--[[linux-4.4.1/validate_mmap_request()]]
/* we ignore the address hint */
addr = 0;
len = PAGE_ALIGN(len);
-
--[[linux-4.4.1/PAGE_ALIGN()]]
/* we've determined that we can make the mapping...
* now know into VMA flags */
vm_flags |= determine_vm_flags(file, prot, flags...
-
--[[linux-4.4.1/determine_vm_flags()]]
/* we're going to need to record the mapping */
region = kmem_cache_zalloc(vm_region_jar, GFP_KE...
if (!region)
goto error_getting_region;
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERN...
if (!vma)
goto error_getting_vma;
-
--[[linux-4.4.1/kmem_cache_zalloc()]]
--[[linux-4.4.1/GFP_KERNEL]]
--[[linux-4.4.1/vm_region_jar(global)]]
--[[linux-4.4.1/vm_area_cachep(global)]]
region->vm_usage = 1;
region->vm_flags = vm_flags;
region->vm_pgoff = pgoff;
INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_flags = vm_flags;
vma->vm_pgoff = pgoff;
if (file) {
region->vm_file = get_file(file);
vma->vm_file = get_file(file);
}
-
--[[linux-4.4.1/INIT_LIST_HEAD()]]
--[[linux-4.4.1/get_file()]]
down_write(&nommu_region_sem);
-
--[[linux-4.4.1/down_write()]]
/* if we want to share, we need to check for reg...
* mmap() calls that overlap with our proposed m...
* - we can only share with a superset match on ...
* - shared mappings on character devices and me...
* permitted to overlap inexactly as far as we...
* these cases, sharing is handled in the driv...
* than here
*/
if (vm_flags & VM_MAYSHARE) {
struct vm_region *pregion;
unsigned long pglen, rpglen, pgend, rpge...
-
--[[linux-4.4.1/VM_MAYSHARE]]
--[[linux-4.4.1/vm_region]]
pglen = (len + PAGE_SIZE - 1) >> PAGE_SH...
pgend = pgoff + pglen;
-
--[[linux-4.4.1/PAGE_SHIFT]]
for (rb = rb_first(&nommu_region_tree); ...
pregion = rb_entry(rb, struct vm...
-
--[[linux-4.4.1/rb_first()]]
--[[linux-4.4.1/nommu_region_tree(global)]]
--[[linux-4.4.1/rb_next()]]
--[[linux-4.4.1/rb_entry()]]
--[[linux-4.4.1/vm_region]]
if (!(pregion->vm_flags & VM_MAY...
continue;
/* search for overlapping mappin...
if (file_inode(pregion->vm_file)...
file_inode(file))
continue;
-
--[[linux-4.4.1/file_inode()]]
if (pregion->vm_pgoff >= pgend)
continue;
rpglen = pregion->vm_end - pregi...
rpglen = (rpglen + PAGE_SIZE - 1...
rpgend = pregion->vm_pgoff + rpg...
if (pgoff >= rpgend)
continue;
/* handle inexactly overlapping ...
* mappings */
if ((pregion->vm_pgoff != pgoff ...
!(pgoff >= pregion->vm_pgoff...
/* new mapping is not a ...
if (!(capabilities & NOM...
goto sharing_vio...
continue;
}
/* we've found a region we can s...
pregion->vm_usage++;
vma->vm_region = pregion;
start = pregion->vm_start;
start += (pgoff - pregion->vm_pg...
vma->vm_start = start;
vma->vm_end = start + len;
if (pregion->vm_flags & VM_MAPPE...
vma->vm_flags |= VM_MAPP...
else {
ret = do_mmap_shared_fil...
if (ret < 0) {
vma->vm_region =...
vma->vm_start = 0;
vma->vm_end = 0;
pregion->vm_usag...
pregion = NULL;
goto error_just_...
}
}
-
--[[linux-4.4.1/do_mmap_shared_file()]]
fput(region->vm_file);
kmem_cache_free(vm_region_jar, r...
region = pregion;
result = start;
goto share;
-
--[[linux-4.4.1/fput()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
}
/* obtain the address at which to make a...
* - this is the hook for quasi-memory c...
* tell us the location of a shared ma...
*/
if (capabilities & NOMMU_MAP_DIRECT) {
addr = file->f_op->get_unmapped_...
...
-file->f_op は const struct file_operations * 型
--[[linux-4.4.1/file_operations]]
if (IS_ERR_VALUE(addr)) {
-
--[[linux-4.4.1/IS_ERR_VALUE()]]
ret = addr;
if (ret != -ENOSYS)
goto error_just_...
/* the driver refused to...
* the mapping so we'll ...
* it */
ret = -ENODEV;
if (!(capabilities & NOM...
goto error_just_...
capabilities &= ~NOMMU_M...
-
--[[linux-4.4.1/NOMMU_MAP_COPY]]
--[[linux-4.4.1/NOMMU_MAP_DIRECT]]
} else {
vma->vm_start = region->...
vma->vm_end = region->vm...
}
}
}
vma->vm_region = region;
/* set up the mapping
* - the region is filled in if NOMMU_MAP_DIRECT...
*/
if (file && vma->vm_flags & VM_SHARED)
ret = do_mmap_shared_file(vma);
else
ret = do_mmap_private(vma, region, len, ...
if (ret < 0)
goto error_just_free;
add_nommu_region(region);
-
--[[linux-4.4.1/do_mmap_shared_file()]]
--[[linux-4.4.1/do_mmap_private()]]
--[[linux-4.4.1/add_nommu_region()]]
--[[linux-4.4.1/VM_SHARED]]
/* clear anonymous mappings that don't ask for u...
if (!vma->vm_file && !(flags & MAP_UNINITIALIZED))
memset((void *)region->vm_start, 0,
region->vm_end - region->vm_start);
/* okay... we have a mapping; now we have to reg...
result = vma->vm_start;
current->mm->total_vm += len >> PAGE_SHIFT;
-
--[[linux-4.4.1/current(global)]]
--[[linux-4.4.1/PAGE_SHIFT]]
share:
add_vma_to_mm(current->mm, vma);
-
--[[linux-4.4.1/add_vma_to_mm()]]
/* we flush the region from the icache only when...
* mapping of it is made */
if (vma->vm_flags & VM_EXEC && !region->vm_icach...
flush_icache_range(region->vm_start, reg...
region->vm_icache_flushed = true;
}
-
--[[linux-4.4.1/flush_icache_range()]]
up_write(&nommu_region_sem);
-
--[[linux-4.4.1/up_write()]]
--[[linux-4.4.1/nommu_region_sem(global)]]
return result;
error_just_free:
up_write(&nommu_region_sem);
error:
if (region->vm_file)
fput(region->vm_file);
kmem_cache_free(vm_region_jar, region);
if (vma->vm_file)
fput(vma->vm_file);
kmem_cache_free(vm_area_cachep, vma);
return ret;
-
--[[linux-4.4.1/fput()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
--[[linux-4.4.1/vm_area_cachep(global)]]
sharing_violation:
up_write(&nommu_region_sem);
pr_warn("Attempt to share mismatched mappings\n");
ret = -EINVAL;
goto error;
-
--[[linux-4.4.1/pr_warn()]]
error_getting_vma:
kmem_cache_free(vm_region_jar, region);
pr_warn("Allocation of vma for %lu byte allocati...
len, current->pid);
show_free_areas(0);
return -ENOMEM;
-
--[[linux-4.4.1/show_free_areas()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
error_getting_region:
pr_warn("Allocation of vm region for %lu byte al...
len, current->pid);
show_free_areas(0);
return -ENOMEM;
}
*コメント [#m8ce7d4f]
終了行:
*参照元 [#u26fa5e1]
#backlinks
*説明 [#s33392ff]
-パス: 複数あり
--CONFIG_MMU 有効: [[linux-4.4.1/mm/mmap.c]]
--CONFIG_MMU 無効: [[linux-4.4.1/mm/nommu.c]]
-FIXME: これは何?
--説明
**引数 [#md56d548]
-struct file *file
--
--[[linux-4.4.1/file]]
-unsigned long addr
--
-unsigned long len
--
-unsigned long prot
--
-unsigned long flags
--
-vm_flags_t vm_flags
-
--[[linux-4.4.1/vm_flags_t]]
-unsigned long pgoff
--
-unsigned long *populate
--
**返り値 [#a7f2941d]
-unsigned long
--
**参考 [#dd70ae03]
*実装 [#b3e8556d]
**CONFIG_MMU 有効: mm/mmap.c [#r7ba5410]
/*
* The caller must hold down_write(¤t->mm->mmap_se...
*/
unsigned long do_mmap(struct file *file, unsigned long a...
unsigned long len, unsigned long...
unsigned long flags, vm_flags_t ...
unsigned long pgoff, unsigned lo...
{
struct mm_struct *mm = current->mm;
-
--[[linux-4.4.1/mm_struct]]
--[[linux-4.4.1/current(global)]]
*populate = 0;
if (!len)
return -EINVAL;
/*
* Does the application expect PROT_READ to impl...
*
* (the exception is when the underlying filesys...
* mounted, in which case we dont add PROT_EXEC.)
*/
if ((prot & PROT_READ) && (current->personality ...
if (!(file && path_noexec(&file->f_path)))
prot |= PROT_EXEC;
-
--[[linux-4.4.1/PROT_READ]]
--[[linux-4.4.1/path_noexec()]]
--[[linux-4.4.1/PROT_EXEC]]
if (!(flags & MAP_FIXED))
addr = round_hint_to_min(addr);
-
--[[linux-4.4.1/MAP_FIXED]]
--[[linux-4.4.1/round_hint_to_min()]]
/* Careful about overflows.. */
len = PAGE_ALIGN(len);
if (!len)
return -ENOMEM;
-
--[[linux-4.4.1/PAGE_ALIGN()]]
/* offset overflow? */
if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
return -EOVERFLOW;
/* Too many mappings? */
if (mm->map_count > sysctl_max_map_count)
return -ENOMEM;
/* Obtain the address to map to. we verify (or s...
* that it represents a valid section of the add...
*/
addr = get_unmapped_area(file, addr, len, pgoff,...
if (offset_in_page(addr))
return addr;
-
--[[linux-4.4.1/get_unmmapped_area()]]
--[[linux-4.4.1/offset_in_page()]]
/* Do simple checking here so the lower-level ro...
* to. we assume access permissions have been ha...
* of the memory object, so we don't do any here.
*/
vm_flags |= calc_vm_prot_bits(prot) | calc_vm_fl...
mm->def_flags | VM_MAYREAD | VM_...
-
--[[linux-4.4.1/calc_vm_prot_bits()]]
--[[linux-4.4.1/calc_vm_flag_bis()]]
--[[linux-4.4.1/VM_MAYREAD]]
--[[linux-4.4.1/VM_MAYWRITE]]
--[[linux-4.4.1/VM_MAY_EXEC]]
if (flags & MAP_LOCKED)
if (!can_do_mlock())
return -EPERM;
-
--[[linux-4.4.1/MAP_LOCKED]]
--[[linux-4.4.1/can_do_mlock()]]
if (mlock_future_check(mm, vm_flags, len))
return -EAGAIN;
-
--[[linux-4.4.1/mlock_future_check()]]
if (file) {
struct inode *inode = file_inode(file);
-
--[[linux-4.4.1/inode]]
--[[linux-4.4.1/file_inode()]]
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if ((prot&PROT_WRITE) && !(file-...
return -EACCES;
/*
* Make sure we don't allow writ...
* file..
*/
if (IS_APPEND(inode) && (file->f...
return -EACCES;
-
--[[linux-4.4.1/IS_APPEND()]]
/*
* Make sure there are no mandat...
*/
if (locks_verify_locked(file))
return -EAGAIN;
-
--[[linux-4.4.1/locks_verify_locked()]]
vm_flags |= VM_SHARED | VM_MAYSH...
if (!(file->f_mode & FMODE_WRITE))
vm_flags &= ~(VM_MAYWRIT...
/* fall through */
case MAP_PRIVATE:
if (!(file->f_mode & FMODE_READ))
return -EACCES;
if (path_noexec(&file->f_path)) {
if (vm_flags & VM_EXEC)
return -EPERM;
vm_flags &= ~VM_MAYEXEC;
}
if (!file->f_op->mmap)
return -ENODEV;
if (vm_flags & (VM_GROWSDOWN|VM_...
return -EINVAL;
break;
default:
return -EINVAL;
}
} else {
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if (vm_flags & (VM_GROWSDOWN|VM_...
return -EINVAL;
/*
* Ignore pgoff.
*/
pgoff = 0;
vm_flags |= VM_SHARED | VM_MAYSH...
break;
case MAP_PRIVATE:
/*
* Set pgoff according to addr f...
*/
pgoff = addr >> PAGE_SHIFT;
break;
default:
return -EINVAL;
}
}
/*
* Set 'VM_NORESERVE' if we should not account f...
* memory use of this mapping.
*/
if (flags & MAP_NORESERVE) {
/* We honor MAP_NORESERVE if allowed to ...
if (sysctl_overcommit_memory != OVERCOMM...
vm_flags |= VM_NORESERVE;
-
--[[linux-4.4.1/sysctl_overcommit_memory(global)]]
--[[linux-4.4.1/OVERCOMMIT_NEVER]]
--[[linux-4.4.1/VM_NORESERVE]]
/* hugetlb applies strict overcommit unl...
if (file && is_file_hugepages(file))
vm_flags |= VM_NORESERVE;
}
addr = mmap_region(file, addr, len, vm_flags, pg...
-
--[[linux-4.4.1/mmap_region()]]
if (!IS_ERR_VALUE(addr) &&
((vm_flags & VM_LOCKED) ||
(flags & (MAP_POPULATE | MAP_NONBLOCK)) == ...
*populate = len;
return addr;
}
**CONFIG_MMU 無効: mm/nommu.c [#n2c5c527]
/*
* handle mapping creation for uClinux
*/
unsigned long do_mmap(struct file *file,
unsigned long addr,
unsigned long len,
unsigned long prot,
unsigned long flags,
vm_flags_t vm_flags,
unsigned long pgoff,
unsigned long *populate)
{
struct vm_area_struct *vma;
struct vm_region *region;
struct rb_node *rb;
unsigned long capabilities, result;
int ret;
-
--[[linux-4.4.1/vm_area_struct]]
--[[linux-4.4.1/vm_region]]
--[[linux-4.4.1/rb_node]]
*populate = 0;
/* decide whether we should attempt the mapping,...
* mapping */
ret = validate_mmap_request(file, addr, len, pro...
&capabilities);
if (ret < 0)
return ret;
-
--[[linux-4.4.1/validate_mmap_request()]]
/* we ignore the address hint */
addr = 0;
len = PAGE_ALIGN(len);
-
--[[linux-4.4.1/PAGE_ALIGN()]]
/* we've determined that we can make the mapping...
* now know into VMA flags */
vm_flags |= determine_vm_flags(file, prot, flags...
-
--[[linux-4.4.1/determine_vm_flags()]]
/* we're going to need to record the mapping */
region = kmem_cache_zalloc(vm_region_jar, GFP_KE...
if (!region)
goto error_getting_region;
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERN...
if (!vma)
goto error_getting_vma;
-
--[[linux-4.4.1/kmem_cache_zalloc()]]
--[[linux-4.4.1/GFP_KERNEL]]
--[[linux-4.4.1/vm_region_jar(global)]]
--[[linux-4.4.1/vm_area_cachep(global)]]
region->vm_usage = 1;
region->vm_flags = vm_flags;
region->vm_pgoff = pgoff;
INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_flags = vm_flags;
vma->vm_pgoff = pgoff;
if (file) {
region->vm_file = get_file(file);
vma->vm_file = get_file(file);
}
-
--[[linux-4.4.1/INIT_LIST_HEAD()]]
--[[linux-4.4.1/get_file()]]
down_write(&nommu_region_sem);
-
--[[linux-4.4.1/down_write()]]
/* if we want to share, we need to check for reg...
* mmap() calls that overlap with our proposed m...
* - we can only share with a superset match on ...
* - shared mappings on character devices and me...
* permitted to overlap inexactly as far as we...
* these cases, sharing is handled in the driv...
* than here
*/
if (vm_flags & VM_MAYSHARE) {
struct vm_region *pregion;
unsigned long pglen, rpglen, pgend, rpge...
-
--[[linux-4.4.1/VM_MAYSHARE]]
--[[linux-4.4.1/vm_region]]
pglen = (len + PAGE_SIZE - 1) >> PAGE_SH...
pgend = pgoff + pglen;
-
--[[linux-4.4.1/PAGE_SHIFT]]
for (rb = rb_first(&nommu_region_tree); ...
pregion = rb_entry(rb, struct vm...
-
--[[linux-4.4.1/rb_first()]]
--[[linux-4.4.1/nommu_region_tree(global)]]
--[[linux-4.4.1/rb_next()]]
--[[linux-4.4.1/rb_entry()]]
--[[linux-4.4.1/vm_region]]
if (!(pregion->vm_flags & VM_MAY...
continue;
/* search for overlapping mappin...
if (file_inode(pregion->vm_file)...
file_inode(file))
continue;
-
--[[linux-4.4.1/file_inode()]]
if (pregion->vm_pgoff >= pgend)
continue;
rpglen = pregion->vm_end - pregi...
rpglen = (rpglen + PAGE_SIZE - 1...
rpgend = pregion->vm_pgoff + rpg...
if (pgoff >= rpgend)
continue;
/* handle inexactly overlapping ...
* mappings */
if ((pregion->vm_pgoff != pgoff ...
!(pgoff >= pregion->vm_pgoff...
/* new mapping is not a ...
if (!(capabilities & NOM...
goto sharing_vio...
continue;
}
/* we've found a region we can s...
pregion->vm_usage++;
vma->vm_region = pregion;
start = pregion->vm_start;
start += (pgoff - pregion->vm_pg...
vma->vm_start = start;
vma->vm_end = start + len;
if (pregion->vm_flags & VM_MAPPE...
vma->vm_flags |= VM_MAPP...
else {
ret = do_mmap_shared_fil...
if (ret < 0) {
vma->vm_region =...
vma->vm_start = 0;
vma->vm_end = 0;
pregion->vm_usag...
pregion = NULL;
goto error_just_...
}
}
-
--[[linux-4.4.1/do_mmap_shared_file()]]
fput(region->vm_file);
kmem_cache_free(vm_region_jar, r...
region = pregion;
result = start;
goto share;
-
--[[linux-4.4.1/fput()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
}
/* obtain the address at which to make a...
* - this is the hook for quasi-memory c...
* tell us the location of a shared ma...
*/
if (capabilities & NOMMU_MAP_DIRECT) {
addr = file->f_op->get_unmapped_...
...
-file->f_op は const struct file_operations * 型
--[[linux-4.4.1/file_operations]]
if (IS_ERR_VALUE(addr)) {
-
--[[linux-4.4.1/IS_ERR_VALUE()]]
ret = addr;
if (ret != -ENOSYS)
goto error_just_...
/* the driver refused to...
* the mapping so we'll ...
* it */
ret = -ENODEV;
if (!(capabilities & NOM...
goto error_just_...
capabilities &= ~NOMMU_M...
-
--[[linux-4.4.1/NOMMU_MAP_COPY]]
--[[linux-4.4.1/NOMMU_MAP_DIRECT]]
} else {
vma->vm_start = region->...
vma->vm_end = region->vm...
}
}
}
vma->vm_region = region;
/* set up the mapping
* - the region is filled in if NOMMU_MAP_DIRECT...
*/
if (file && vma->vm_flags & VM_SHARED)
ret = do_mmap_shared_file(vma);
else
ret = do_mmap_private(vma, region, len, ...
if (ret < 0)
goto error_just_free;
add_nommu_region(region);
-
--[[linux-4.4.1/do_mmap_shared_file()]]
--[[linux-4.4.1/do_mmap_private()]]
--[[linux-4.4.1/add_nommu_region()]]
--[[linux-4.4.1/VM_SHARED]]
/* clear anonymous mappings that don't ask for u...
if (!vma->vm_file && !(flags & MAP_UNINITIALIZED))
memset((void *)region->vm_start, 0,
region->vm_end - region->vm_start);
/* okay... we have a mapping; now we have to reg...
result = vma->vm_start;
current->mm->total_vm += len >> PAGE_SHIFT;
-
--[[linux-4.4.1/current(global)]]
--[[linux-4.4.1/PAGE_SHIFT]]
share:
add_vma_to_mm(current->mm, vma);
-
--[[linux-4.4.1/add_vma_to_mm()]]
/* we flush the region from the icache only when...
* mapping of it is made */
if (vma->vm_flags & VM_EXEC && !region->vm_icach...
flush_icache_range(region->vm_start, reg...
region->vm_icache_flushed = true;
}
-
--[[linux-4.4.1/flush_icache_range()]]
up_write(&nommu_region_sem);
-
--[[linux-4.4.1/up_write()]]
--[[linux-4.4.1/nommu_region_sem(global)]]
return result;
error_just_free:
up_write(&nommu_region_sem);
error:
if (region->vm_file)
fput(region->vm_file);
kmem_cache_free(vm_region_jar, region);
if (vma->vm_file)
fput(vma->vm_file);
kmem_cache_free(vm_area_cachep, vma);
return ret;
-
--[[linux-4.4.1/fput()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
--[[linux-4.4.1/vm_area_cachep(global)]]
sharing_violation:
up_write(&nommu_region_sem);
pr_warn("Attempt to share mismatched mappings\n");
ret = -EINVAL;
goto error;
-
--[[linux-4.4.1/pr_warn()]]
error_getting_vma:
kmem_cache_free(vm_region_jar, region);
pr_warn("Allocation of vma for %lu byte allocati...
len, current->pid);
show_free_areas(0);
return -ENOMEM;
-
--[[linux-4.4.1/show_free_areas()]]
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_region_jar(global)]]
error_getting_region:
pr_warn("Allocation of vm region for %lu byte al...
len, current->pid);
show_free_areas(0);
return -ENOMEM;
}
*コメント [#m8ce7d4f]
ページ名: