linux-4.4.1/mmap_region()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#nd347716]
#backlinks
*説明 [#i48a49d5]
-パス: [[linux-4.4.1/mm/mmap.c]]
-FIXME: これは何?
--説明
**引数 [#xc9c5a62]
-struct file *file
--
--[[linux-4.4.1/file]]
-unsigned long addr
--
-unsigned long len
--
-vm_flags_t vm_flags
--
--[[linux-4.4.1/vm_flags_t]]
-unsigned long pgoff
--
**返り値 [#cb565d7e]
-unsigned long
--
**参考 [#i0ffaa70]
*実装 [#s7ea96a4]
unsigned long mmap_region(struct file *file, unsigned lo...
unsigned long len, vm_flags_t vm_flags, ...
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
int error;
struct rb_node **rb_link, *rb_parent;
unsigned long charged = 0;
-
--[[linux-4.4.1/mm_struct]]
--[[linux-4.4.1/current(global)]]
--[[linux-4.4.1/vm_area_struct]]
--[[linux-4.4.1/rb_node]]
/* Check against address space limit. */
if (!may_expand_vm(mm, len >> PAGE_SHIFT)) {
unsigned long nr_pages;
-
--[[linux-4.4.1/may_expand_vm()]]
--[[linux-4.4.1/PAGE_SHIFT]]
/*
* MAP_FIXED may remove pages of mapping...
* requested mapping. Account for the pa...
*/
if (!(vm_flags & MAP_FIXED))
return -ENOMEM;
-
--[[linux-4.4.1/MAP_FIXED]]
nr_pages = count_vma_pages_range(mm, add...
-
--[[linux-4.4.1/count_vma_pages_range()]]
if (!may_expand_vm(mm, (len >> PAGE_SHIF...
return -ENOMEM;
}
/* Clear old maps */
while (find_vma_links(mm, addr, addr + len, &pre...
&rb_parent)) {
if (do_munmap(mm, addr, len))
return -ENOMEM;
}
-
--[[linux-4.4.1/find_vma_links()]]
--[[linux-4.4.1/do_munmap()]]
/*
* Private writable mapping: check memory availa...
*/
if (accountable_mapping(file, vm_flags)) {
charged = len >> PAGE_SHIFT;
if (security_vm_enough_memory_mm(mm, cha...
return -ENOMEM;
vm_flags |= VM_ACCOUNT;
}
-
--[[linux-4.4.1/accountable_mapping()]]
--[[linux-4.4.1/security_vm_enough_memory_mm()]]
/*
* Can we just expand an old mapping?
*/
vma = vma_merge(mm, prev, addr, addr + len, vm_f...
NULL, file, pgoff, NULL, NULL_VM...
if (vma)
goto out;
-
--[[linux-4.4.1/vma_merge()]]
/*
* Determine the object being mapped and call th...
* specific mapper. the address has already been...
* not unmapped, but the maps are removed from t...
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERN...
if (!vma) {
error = -ENOMEM;
goto unacct_error;
}
-
--[[linux-4.4.1/kmem_cache_zalloc()]]
--[[linux-4.4.1/vm_area_cachep(global)]]
--[[linux-4.4.1/GFP_KERNEL]]
vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
vma->vm_flags = vm_flags;
vma->vm_page_prot = vm_get_page_prot(vm_flags);
vma->vm_pgoff = pgoff;
INIT_LIST_HEAD(&vma->anon_vma_chain);
-
--[[linux-4.4.1/vm_get_page_prot()]]
--[[linux-4.4.1/INIT_LIST_HEAD()]]
if (file) {
if (vm_flags & VM_DENYWRITE) {
error = deny_write_access(file);
if (error)
goto free_vma;
}
-
--[[linux-4.4.1/VM_DENYWRITE]]
--[[linux-4.4.1/deny_write_access()]]
if (vm_flags & VM_SHARED) {
error = mapping_map_writable(fil...
if (error)
goto allow_write_and_fre...
}
-
--[[linux-4.4.1/VM_SHARED]]
--[[linux-4.4.1/mapping_map_writable()]]
/* ->mmap() can change vma->vm_file, but...
* vma_link() below can deny write-acces...
* and map writably if VM_SHARED is set....
* new file must not have been exposed t...
*/
vma->vm_file = get_file(file);
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
-
-file->f_op は 型
--[[linux-4.4.1/]]
--[[linux-4.4.1/get_file()]]
/* Can addr have changed??
*
* Answer: Yes, several device drivers c...
* f_op->mmap method. -DaveM
* Bug: If addr is changed, prev, rb_lin...
* be updated for vma_link()
*/
WARN_ON_ONCE(addr != vma->vm_start);
addr = vma->vm_start;
vm_flags = vma->vm_flags;
-
--[[linux-4.4.1/WARN_ON_ONCE()]]
} else if (vm_flags & VM_SHARED) {
error = shmem_zero_setup(vma);
if (error)
goto free_vma;
-
--[[linux-4.4.1/shmem_zero_setup()]]
}
vma_link(mm, vma, prev, rb_link, rb_parent);
-
--[[linux-4.4.1/vma_link()]]
/* Once vma denies write, undo our temporary den...
if (file) {
if (vm_flags & VM_SHARED)
mapping_unmap_writable(file->f_m...
if (vm_flags & VM_DENYWRITE)
allow_write_access(file);
}
file = vma->vm_file;
-
--[[linux-4.4.1/mapping_unmap_writable()]]
--[[linux-4.4.1/allow_write_access()]]
--[[linux-4.4.1/VM_SHARED]]
--[[linux-4.4.1/VM_DENYWRITE]]
out:
perf_event_mmap(vma);
-
--[[linux-4.4.1/perf_event_mmap()]]
vm_stat_account(mm, vm_flags, file, len >> PAGE_...
-
--[[linux-4.4.1/vm_stat_account()]]
if (vm_flags & VM_LOCKED) {
if (!((vm_flags & VM_SPECIAL) || is_vm_h...
vma == get_gate_...
mm->locked_vm += (len >> PAGE_SH...
else
vma->vm_flags &= VM_LOCKED_CLEAR...
}
-
--[[linux-4.4.1/VM_LOCKED]]
--[[linux-4.4.1/is_vm_hugetlb_page()]]
--[[linux-4.4.1/get_gate_vma()]]
--[[linux-4.4.1/PAGE_SHIFT]]
--[[linux-4.4.1/VM_LOCKED_CLEAR_MASK]]
if (file)
uprobe_mmap(vma);
-
--[[linux-4.4.1/uprobe_mmap()]]
/*
* New (or expanded) vma always get soft dirty s...
* Otherwise user-space soft-dirty page tracker ...
* be able to distinguish situation when vma are...
* then new mapped in-place (which must be aimed...
* a completely new data area).
*/
vma->vm_flags |= VM_SOFTDIRTY;
vma_set_page_prot(vma);
return addr;
-
--[[linux-4.4.1/VM_SOFTDIRTY]]
--[[linux-4.4.1/vma_set_page_prot()]]
unmap_and_free_vma:
vma->vm_file = NULL;
fput(file);
-
--[[linux-4.4.1/fput()]]
/* Undo any partial mapping done by a device dri...
unmap_region(mm, vma, prev, vma->vm_start, vma->...
charged = 0;
if (vm_flags & VM_SHARED)
mapping_unmap_writable(file->f_mapping);
-
--[[linux-4.4.1/unmap_region()]]
--[[linux-4.4.1/mapping_unmap_writable()]]
allow_write_and_free_vma:
if (vm_flags & VM_DENYWRITE)
allow_write_access(file);
-
--[[linux-4.4.1/VM_DENYWRITE]]
--[[linux-4.4.1/allow_write_access()]]
free_vma:
kmem_cache_free(vm_area_cachep, vma);
-
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_area_cachep(global)]]
unacct_error:
if (charged)
vm_unacct_memory(charged);
-
--[[linux-4.4.1/vm_unacct_memory()]]
return error;
}
*コメント [#l56e3b36]
終了行:
*参照元 [#nd347716]
#backlinks
*説明 [#i48a49d5]
-パス: [[linux-4.4.1/mm/mmap.c]]
-FIXME: これは何?
--説明
**引数 [#xc9c5a62]
-struct file *file
--
--[[linux-4.4.1/file]]
-unsigned long addr
--
-unsigned long len
--
-vm_flags_t vm_flags
--
--[[linux-4.4.1/vm_flags_t]]
-unsigned long pgoff
--
**返り値 [#cb565d7e]
-unsigned long
--
**参考 [#i0ffaa70]
*実装 [#s7ea96a4]
unsigned long mmap_region(struct file *file, unsigned lo...
unsigned long len, vm_flags_t vm_flags, ...
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma, *prev;
int error;
struct rb_node **rb_link, *rb_parent;
unsigned long charged = 0;
-
--[[linux-4.4.1/mm_struct]]
--[[linux-4.4.1/current(global)]]
--[[linux-4.4.1/vm_area_struct]]
--[[linux-4.4.1/rb_node]]
/* Check against address space limit. */
if (!may_expand_vm(mm, len >> PAGE_SHIFT)) {
unsigned long nr_pages;
-
--[[linux-4.4.1/may_expand_vm()]]
--[[linux-4.4.1/PAGE_SHIFT]]
/*
* MAP_FIXED may remove pages of mapping...
* requested mapping. Account for the pa...
*/
if (!(vm_flags & MAP_FIXED))
return -ENOMEM;
-
--[[linux-4.4.1/MAP_FIXED]]
nr_pages = count_vma_pages_range(mm, add...
-
--[[linux-4.4.1/count_vma_pages_range()]]
if (!may_expand_vm(mm, (len >> PAGE_SHIF...
return -ENOMEM;
}
/* Clear old maps */
while (find_vma_links(mm, addr, addr + len, &pre...
&rb_parent)) {
if (do_munmap(mm, addr, len))
return -ENOMEM;
}
-
--[[linux-4.4.1/find_vma_links()]]
--[[linux-4.4.1/do_munmap()]]
/*
* Private writable mapping: check memory availa...
*/
if (accountable_mapping(file, vm_flags)) {
charged = len >> PAGE_SHIFT;
if (security_vm_enough_memory_mm(mm, cha...
return -ENOMEM;
vm_flags |= VM_ACCOUNT;
}
-
--[[linux-4.4.1/accountable_mapping()]]
--[[linux-4.4.1/security_vm_enough_memory_mm()]]
/*
* Can we just expand an old mapping?
*/
vma = vma_merge(mm, prev, addr, addr + len, vm_f...
NULL, file, pgoff, NULL, NULL_VM...
if (vma)
goto out;
-
--[[linux-4.4.1/vma_merge()]]
/*
* Determine the object being mapped and call th...
* specific mapper. the address has already been...
* not unmapped, but the maps are removed from t...
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERN...
if (!vma) {
error = -ENOMEM;
goto unacct_error;
}
-
--[[linux-4.4.1/kmem_cache_zalloc()]]
--[[linux-4.4.1/vm_area_cachep(global)]]
--[[linux-4.4.1/GFP_KERNEL]]
vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
vma->vm_flags = vm_flags;
vma->vm_page_prot = vm_get_page_prot(vm_flags);
vma->vm_pgoff = pgoff;
INIT_LIST_HEAD(&vma->anon_vma_chain);
-
--[[linux-4.4.1/vm_get_page_prot()]]
--[[linux-4.4.1/INIT_LIST_HEAD()]]
if (file) {
if (vm_flags & VM_DENYWRITE) {
error = deny_write_access(file);
if (error)
goto free_vma;
}
-
--[[linux-4.4.1/VM_DENYWRITE]]
--[[linux-4.4.1/deny_write_access()]]
if (vm_flags & VM_SHARED) {
error = mapping_map_writable(fil...
if (error)
goto allow_write_and_fre...
}
-
--[[linux-4.4.1/VM_SHARED]]
--[[linux-4.4.1/mapping_map_writable()]]
/* ->mmap() can change vma->vm_file, but...
* vma_link() below can deny write-acces...
* and map writably if VM_SHARED is set....
* new file must not have been exposed t...
*/
vma->vm_file = get_file(file);
error = file->f_op->mmap(file, vma);
if (error)
goto unmap_and_free_vma;
-
-file->f_op は 型
--[[linux-4.4.1/]]
--[[linux-4.4.1/get_file()]]
/* Can addr have changed??
*
* Answer: Yes, several device drivers c...
* f_op->mmap method. -DaveM
* Bug: If addr is changed, prev, rb_lin...
* be updated for vma_link()
*/
WARN_ON_ONCE(addr != vma->vm_start);
addr = vma->vm_start;
vm_flags = vma->vm_flags;
-
--[[linux-4.4.1/WARN_ON_ONCE()]]
} else if (vm_flags & VM_SHARED) {
error = shmem_zero_setup(vma);
if (error)
goto free_vma;
-
--[[linux-4.4.1/shmem_zero_setup()]]
}
vma_link(mm, vma, prev, rb_link, rb_parent);
-
--[[linux-4.4.1/vma_link()]]
/* Once vma denies write, undo our temporary den...
if (file) {
if (vm_flags & VM_SHARED)
mapping_unmap_writable(file->f_m...
if (vm_flags & VM_DENYWRITE)
allow_write_access(file);
}
file = vma->vm_file;
-
--[[linux-4.4.1/mapping_unmap_writable()]]
--[[linux-4.4.1/allow_write_access()]]
--[[linux-4.4.1/VM_SHARED]]
--[[linux-4.4.1/VM_DENYWRITE]]
out:
perf_event_mmap(vma);
-
--[[linux-4.4.1/perf_event_mmap()]]
vm_stat_account(mm, vm_flags, file, len >> PAGE_...
-
--[[linux-4.4.1/vm_stat_account()]]
if (vm_flags & VM_LOCKED) {
if (!((vm_flags & VM_SPECIAL) || is_vm_h...
vma == get_gate_...
mm->locked_vm += (len >> PAGE_SH...
else
vma->vm_flags &= VM_LOCKED_CLEAR...
}
-
--[[linux-4.4.1/VM_LOCKED]]
--[[linux-4.4.1/is_vm_hugetlb_page()]]
--[[linux-4.4.1/get_gate_vma()]]
--[[linux-4.4.1/PAGE_SHIFT]]
--[[linux-4.4.1/VM_LOCKED_CLEAR_MASK]]
if (file)
uprobe_mmap(vma);
-
--[[linux-4.4.1/uprobe_mmap()]]
/*
* New (or expanded) vma always get soft dirty s...
* Otherwise user-space soft-dirty page tracker ...
* be able to distinguish situation when vma are...
* then new mapped in-place (which must be aimed...
* a completely new data area).
*/
vma->vm_flags |= VM_SOFTDIRTY;
vma_set_page_prot(vma);
return addr;
-
--[[linux-4.4.1/VM_SOFTDIRTY]]
--[[linux-4.4.1/vma_set_page_prot()]]
unmap_and_free_vma:
vma->vm_file = NULL;
fput(file);
-
--[[linux-4.4.1/fput()]]
/* Undo any partial mapping done by a device dri...
unmap_region(mm, vma, prev, vma->vm_start, vma->...
charged = 0;
if (vm_flags & VM_SHARED)
mapping_unmap_writable(file->f_mapping);
-
--[[linux-4.4.1/unmap_region()]]
--[[linux-4.4.1/mapping_unmap_writable()]]
allow_write_and_free_vma:
if (vm_flags & VM_DENYWRITE)
allow_write_access(file);
-
--[[linux-4.4.1/VM_DENYWRITE]]
--[[linux-4.4.1/allow_write_access()]]
free_vma:
kmem_cache_free(vm_area_cachep, vma);
-
--[[linux-4.4.1/kmem_cache_free()]]
--[[linux-4.4.1/vm_area_cachep(global)]]
unacct_error:
if (charged)
vm_unacct_memory(charged);
-
--[[linux-4.4.1/vm_unacct_memory()]]
return error;
}
*コメント [#l56e3b36]
ページ名: