mirror of
https://github.com/drasko/codezero.git
synced 2026-09-29 16:50:22 +02:00
Split vmas had no objects. Now fixed.
When sys_munmap() splits a vma, the new vma had no copy of the objects in the original vma. Now we fixed that using a vma_copy_links() function which can also be used as part of fork().
This commit is contained in:
@@ -252,6 +252,7 @@ static inline void task_add_vma(struct tcb *task, struct vm_area *vma)
|
|||||||
/* Main page fault entry point */
|
/* Main page fault entry point */
|
||||||
int page_fault_handler(struct tcb *faulty_task, fault_kdata_t *fkdata);
|
int page_fault_handler(struct tcb *faulty_task, fault_kdata_t *fkdata);
|
||||||
|
|
||||||
|
int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma);
|
||||||
int vma_drop_merge_delete(struct vm_area *vma, struct vm_obj_link *link);
|
int vma_drop_merge_delete(struct vm_area *vma, struct vm_obj_link *link);
|
||||||
int vma_drop_merge_delete_all(struct vm_area *vma);
|
int vma_drop_merge_delete_all(struct vm_area *vma);
|
||||||
|
|
||||||
|
|||||||
@@ -262,6 +262,32 @@ struct page *copy_to_new_page(struct page *orig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy all mapped object link stack from vma to new vma */
|
||||||
|
int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma)
|
||||||
|
{
|
||||||
|
struct vm_obj_link *vmo_link, *new_link;
|
||||||
|
|
||||||
|
/* Get the first object on the vma */
|
||||||
|
BUG_ON(list_empty(&vma->vm_obj_list));
|
||||||
|
vmo_link = list_entry(vma->vm_obj_list.next,
|
||||||
|
struct vm_obj_link, list);
|
||||||
|
do {
|
||||||
|
/* Create a new link */
|
||||||
|
new_link = vm_objlink_create();
|
||||||
|
|
||||||
|
/* Link object with new link */
|
||||||
|
vm_link_object(new_link, vmo_link->obj);
|
||||||
|
|
||||||
|
/* Add the new link to vma in object order */
|
||||||
|
list_add_tail(&new_link->list, &new_vma->vm_obj_list);
|
||||||
|
|
||||||
|
/* Continue traversing links, doing the same copying */
|
||||||
|
} while((vmo_link = vma_next_link(&vmo_link->list,
|
||||||
|
&vma->vm_obj_list)));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine if an object is deletable.
|
* Determine if an object is deletable.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <l4/api/errno.h>
|
#include <l4/api/errno.h>
|
||||||
#include <l4/lib/math.h>
|
#include <l4/lib/math.h>
|
||||||
#include <l4lib/arch/syslib.h>
|
#include <l4lib/arch/syslib.h>
|
||||||
|
#include <vm_area.h>
|
||||||
|
|
||||||
/* This splits a vma, splitter region must be in the *middle* of original vma */
|
/* This splits a vma, splitter region must be in the *middle* of original vma */
|
||||||
int vma_split(struct vm_area *vma, struct tcb *task,
|
int vma_split(struct vm_area *vma, struct tcb *task,
|
||||||
@@ -33,6 +33,13 @@ int vma_split(struct vm_area *vma, struct tcb *task,
|
|||||||
vma->pfn_end = pfn_start;
|
vma->pfn_end = pfn_start;
|
||||||
new->flags = vma->flags;
|
new->flags = vma->flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the object links of original vma to new vma. A split like this
|
||||||
|
* increases the map count of mapped object(s) since now 2 vmas on the
|
||||||
|
* same task maps the same object(s).
|
||||||
|
*/
|
||||||
|
vma_copy_links(new, vma);
|
||||||
|
|
||||||
/* Add new one next to original vma */
|
/* Add new one next to original vma */
|
||||||
list_add_tail(&new->list, &vma->list);
|
list_add_tail(&new->list, &vma->list);
|
||||||
|
|
||||||
|
|||||||
+2
-18
@@ -129,7 +129,6 @@ int tcb_destroy(struct tcb *task)
|
|||||||
int copy_vmas(struct tcb *to, struct tcb *from)
|
int copy_vmas(struct tcb *to, struct tcb *from)
|
||||||
{
|
{
|
||||||
struct vm_area *vma, *new_vma;
|
struct vm_area *vma, *new_vma;
|
||||||
struct vm_obj_link *vmo_link, *new_link;
|
|
||||||
|
|
||||||
list_for_each_entry(vma, &from->vm_area_head->list, list) {
|
list_for_each_entry(vma, &from->vm_area_head->list, list) {
|
||||||
|
|
||||||
@@ -137,23 +136,8 @@ int copy_vmas(struct tcb *to, struct tcb *from)
|
|||||||
new_vma = vma_new(vma->pfn_start, vma->pfn_end - vma->pfn_start,
|
new_vma = vma_new(vma->pfn_start, vma->pfn_end - vma->pfn_start,
|
||||||
vma->flags, vma->file_offset);
|
vma->flags, vma->file_offset);
|
||||||
|
|
||||||
/* Get the first object on the vma */
|
/* Copy all object links */
|
||||||
BUG_ON(list_empty(&vma->vm_obj_list));
|
vma_copy_links(new_vma, vma);
|
||||||
vmo_link = list_entry(vma->vm_obj_list.next,
|
|
||||||
struct vm_obj_link, list);
|
|
||||||
do {
|
|
||||||
/* Create a new link */
|
|
||||||
new_link = vm_objlink_create();
|
|
||||||
|
|
||||||
/* Link object with new link */
|
|
||||||
vm_link_object(new_link, vmo_link->obj);
|
|
||||||
|
|
||||||
/* Add the new link to vma in object order */
|
|
||||||
list_add_tail(&new_link->list, &new_vma->vm_obj_list);
|
|
||||||
|
|
||||||
/* Continue traversing links, doing the same copying */
|
|
||||||
} while((vmo_link = vma_next_link(&vmo_link->list,
|
|
||||||
&vma->vm_obj_list)));
|
|
||||||
|
|
||||||
/* All link copying is finished, now add the new vma to task */
|
/* All link copying is finished, now add the new vma to task */
|
||||||
task_add_vma(to, new_vma);
|
task_add_vma(to, new_vma);
|
||||||
|
|||||||
Reference in New Issue
Block a user