vm: implement private and shared address space mappings
whether a mapping is private or shared determines how the mapping is handled when a task is duplicated.
This commit is contained in:
+11
-9
@@ -125,6 +125,7 @@ kern_status_t sys_address_space_map(
|
||||
kern_handle_t object_handle,
|
||||
off_t object_offset,
|
||||
size_t length,
|
||||
vm_flags_t flags,
|
||||
vm_prot_t prot,
|
||||
virt_addr_t *out_base_address)
|
||||
{
|
||||
@@ -140,8 +141,8 @@ kern_status_t sys_address_space_map(
|
||||
}
|
||||
|
||||
kern_status_t status = KERN_OK;
|
||||
unsigned long flags;
|
||||
task_lock_irqsave(self, &flags);
|
||||
unsigned long irq_flags;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
|
||||
struct object *region_obj = NULL, *vmo_obj = NULL;
|
||||
handle_flags_t region_flags = 0, vmo_flags = 0;
|
||||
@@ -151,34 +152,34 @@ kern_status_t sys_address_space_map(
|
||||
®ion_obj,
|
||||
®ion_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = task_resolve_handle(self, object_handle, &vmo_obj, &vmo_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct address_space *region = address_space_cast(region_obj);
|
||||
if (!region) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
struct vm_object *vmo = vm_object_cast(vmo_obj);
|
||||
if (!vmo) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
task_unlock_irqrestore(self, flags);
|
||||
address_space_lock_irqsave(region, &flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
address_space_lock_irqsave(region, &irq_flags);
|
||||
/* address_space_map will take care of locking `vmo` */
|
||||
status = address_space_map(
|
||||
region,
|
||||
@@ -186,9 +187,10 @@ kern_status_t sys_address_space_map(
|
||||
vmo,
|
||||
object_offset,
|
||||
length,
|
||||
flags,
|
||||
prot,
|
||||
out_base_address);
|
||||
address_space_unlock_irqrestore(region, flags);
|
||||
address_space_unlock_irqrestore(region, irq_flags);
|
||||
|
||||
object_unref(vmo_obj);
|
||||
object_unref(region_obj);
|
||||
|
||||
@@ -148,8 +148,8 @@ kern_status_t sys_vm_controller_create_object(
|
||||
}
|
||||
|
||||
kern_status_t status = KERN_OK;
|
||||
unsigned long flags;
|
||||
task_lock_irqsave(self, &flags);
|
||||
unsigned long irq_flags;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
|
||||
struct object *ctrl_obj = NULL;
|
||||
handle_flags_t handle_flags = 0;
|
||||
@@ -159,7 +159,7 @@ kern_status_t sys_vm_controller_create_object(
|
||||
&ctrl_obj,
|
||||
&handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
@@ -173,14 +173,14 @@ kern_status_t sys_vm_controller_create_object(
|
||||
&out_handle);
|
||||
|
||||
struct vm_controller *ctrl = vm_controller_cast(ctrl_obj);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
if (!ctrl) {
|
||||
object_unref(ctrl_obj);
|
||||
put_current_task(self);
|
||||
return KERN_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
vm_controller_lock_irqsave(ctrl, &flags);
|
||||
vm_controller_lock_irqsave(ctrl, &irq_flags);
|
||||
struct vm_object *out_vmo = NULL;
|
||||
status = vm_controller_create_object(
|
||||
ctrl,
|
||||
@@ -190,14 +190,14 @@ kern_status_t sys_vm_controller_create_object(
|
||||
data_len,
|
||||
prot,
|
||||
&out_vmo);
|
||||
vm_controller_unlock_irqrestore(ctrl, flags);
|
||||
vm_controller_unlock_irqrestore(ctrl, irq_flags);
|
||||
|
||||
object_unref(ctrl_obj);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
task_lock_irqsave(self, &flags);
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
handle_table_free_handle(self->t_handles, out_handle);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
put_current_task(self);
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user