vm: replace vm-region with address-space
address-space is a non-recursive data structure, which contains a flat list of vm_areas representing mapped vm-objects. userspace programs can no longer create sub-address-spaces. instead, they can reserve portions of the address space, and use that reserved space to create mappings.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/compiler.h>
|
#include <kernel/compiler.h>
|
||||||
#include <kernel/libc/stdio.h>
|
#include <kernel/libc/stdio.h>
|
||||||
#include <kernel/memblock.h>
|
#include <kernel/memblock.h>
|
||||||
@@ -7,7 +8,6 @@
|
|||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
#include <kernel/vm-object.h>
|
#include <kernel/vm-object.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/status.h>
|
#include <mango/status.h>
|
||||||
|
|
||||||
@@ -363,12 +363,20 @@ kern_status_t pmap_handle_fault(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct task *task = current_task();
|
struct task *task = current_task();
|
||||||
struct vm_region *space = task->t_address_space;
|
if (!task) {
|
||||||
|
return KERN_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct address_space *space = task->t_address_space;
|
||||||
|
if (!space) {
|
||||||
|
return KERN_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long lock_flags;
|
unsigned long lock_flags;
|
||||||
vm_region_lock_irqsave(space, &lock_flags);
|
address_space_lock_irqsave(space, &lock_flags);
|
||||||
kern_status_t status = vm_region_demand_map(space, fault_addr, flags);
|
kern_status_t status
|
||||||
vm_region_unlock_irqrestore(space, lock_flags);
|
= address_space_demand_map(space, fault_addr, flags);
|
||||||
|
address_space_unlock_irqrestore(space, lock_flags);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
161
include/kernel/address-space.h
Normal file
161
include/kernel/address-space.h
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
#ifndef KERNEL_ADDRESS_SPACE_H_
|
||||||
|
#define KERNEL_ADDRESS_SPACE_H_
|
||||||
|
|
||||||
|
#include <kernel/object.h>
|
||||||
|
#include <kernel/pmap.h>
|
||||||
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
|
#define ADDRESS_SPACE_COPY_ALL ((size_t)-1)
|
||||||
|
|
||||||
|
struct address_space;
|
||||||
|
struct vm_object;
|
||||||
|
|
||||||
|
struct vm_area {
|
||||||
|
/* the vm-object mapped into this area.
|
||||||
|
* if this is NULL, the vm_area represents an area of reserved memory.
|
||||||
|
* it cannot be accessed, and mapping operations with MAP_ADDRESS_ANY
|
||||||
|
* will avoid the area, but fixed address mappings in this area
|
||||||
|
* will succeed. */
|
||||||
|
struct vm_object *vma_object;
|
||||||
|
/* used to link to vm_object->vo_mappings */
|
||||||
|
struct queue_entry vma_object_entry;
|
||||||
|
/* the memory protection flags applied to this area */
|
||||||
|
vm_prot_t vma_prot;
|
||||||
|
/* offset in bytes to the start of the object data that was mapped */
|
||||||
|
off_t vma_object_offset;
|
||||||
|
/* used to link to address_space->s_mappings */
|
||||||
|
struct btree_node vma_node;
|
||||||
|
/* address of the first byte in this area */
|
||||||
|
virt_addr_t vma_base;
|
||||||
|
/* address of the last byte in this area */
|
||||||
|
virt_addr_t vma_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct address_space {
|
||||||
|
struct object s_base;
|
||||||
|
|
||||||
|
/* address of the first byte in this address space */
|
||||||
|
virt_addr_t s_base_address;
|
||||||
|
/* address of the last byte in this address space */
|
||||||
|
virt_addr_t s_limit_address;
|
||||||
|
|
||||||
|
/* btree of struct vm_area representing mapped vm-objects.
|
||||||
|
* sibling entries cannot overlap each other. */
|
||||||
|
struct btree s_mappings;
|
||||||
|
/* btree of struct vm_area representing reserved regions of the
|
||||||
|
* address space.
|
||||||
|
* reserved regions will not be automatically allocated by the kernel.
|
||||||
|
* sibling entries cannot overlap each other.
|
||||||
|
* overlap between s_mappings and s_reserved IS allowed. */
|
||||||
|
struct btree s_reserved;
|
||||||
|
|
||||||
|
/* the corresponding physical address space */
|
||||||
|
pmap_t s_pmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern kern_status_t address_space_type_init(void);
|
||||||
|
extern struct address_space *address_space_cast(struct object *obj);
|
||||||
|
|
||||||
|
/* create a new vm-region, optionally within a parent region.
|
||||||
|
* `offset` is the byte offset within the parent region where the new region
|
||||||
|
* should start.
|
||||||
|
* if no parent is specified, `offset` is the absolute virtual address of the
|
||||||
|
* start of the region.
|
||||||
|
* in both cases, `len` is the length of the new region in bytes. */
|
||||||
|
extern kern_status_t address_space_create(
|
||||||
|
virt_addr_t base,
|
||||||
|
virt_addr_t limit,
|
||||||
|
struct address_space **out);
|
||||||
|
|
||||||
|
/* map a vm-object into a vm-region.
|
||||||
|
* [region_offset,length] must fall within exactly one region, and cannot span
|
||||||
|
* multiple sibling regions.
|
||||||
|
* if [region_offset,length] falls within a child region, the map operation
|
||||||
|
* will be transparently redirected to the relevant region.
|
||||||
|
* `prot` must be allowed both by the region into which the mapping is being
|
||||||
|
* created AND the vm-object being mapped. */
|
||||||
|
extern kern_status_t address_space_map(
|
||||||
|
struct address_space *space,
|
||||||
|
virt_addr_t map_address,
|
||||||
|
struct vm_object *object,
|
||||||
|
off_t object_offset,
|
||||||
|
size_t length,
|
||||||
|
vm_prot_t prot,
|
||||||
|
virt_addr_t *out);
|
||||||
|
extern kern_status_t address_space_unmap(
|
||||||
|
struct address_space *region,
|
||||||
|
virt_addr_t base,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
/* reserve an area of the address space. the kernel will not place any
|
||||||
|
* new mappings in this area unless explicitly told to (i.e. by not using
|
||||||
|
* MAP_ADDRESS_ANY). Use MAP_ADDRESS_ANY to have the kernel allocate a region
|
||||||
|
* of the address space for you */
|
||||||
|
extern kern_status_t address_space_reserve(
|
||||||
|
struct address_space *space,
|
||||||
|
virt_addr_t base,
|
||||||
|
size_t length,
|
||||||
|
virt_addr_t *out);
|
||||||
|
/* release a previously reserved area of the address space. */
|
||||||
|
extern kern_status_t address_space_release(
|
||||||
|
struct address_space *space,
|
||||||
|
virt_addr_t base,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
extern bool address_space_validate_access(
|
||||||
|
struct address_space *region,
|
||||||
|
virt_addr_t base,
|
||||||
|
size_t len,
|
||||||
|
vm_prot_t prot);
|
||||||
|
|
||||||
|
/* find the mapping corresponding to the given virtual address, and page-in the
|
||||||
|
* necessary vm_page to allow the memory access to succeed. if the relevant
|
||||||
|
* vm-object page hasn't been allocated yet, it will be allocated here. */
|
||||||
|
extern kern_status_t address_space_demand_map(
|
||||||
|
struct address_space *region,
|
||||||
|
virt_addr_t addr,
|
||||||
|
enum pmap_fault_flags flags);
|
||||||
|
|
||||||
|
/* read data from the user-space area of a vm-region into a kernel-mode buffer
|
||||||
|
*/
|
||||||
|
extern kern_status_t address_space_read(
|
||||||
|
struct address_space *src_region,
|
||||||
|
virt_addr_t src_ptr,
|
||||||
|
size_t count,
|
||||||
|
void *dest,
|
||||||
|
size_t *nr_read);
|
||||||
|
|
||||||
|
/* write data to the user-space area of a vm-region from a kernel-mode buffer
|
||||||
|
*/
|
||||||
|
extern kern_status_t address_space_write(
|
||||||
|
struct address_space *dst_region,
|
||||||
|
virt_addr_t dst_ptr,
|
||||||
|
size_t count,
|
||||||
|
const void *src,
|
||||||
|
size_t *nr_written);
|
||||||
|
|
||||||
|
extern kern_status_t address_space_memmove(
|
||||||
|
struct address_space *dest_space,
|
||||||
|
virt_addr_t dest_ptr,
|
||||||
|
struct address_space *src_space,
|
||||||
|
virt_addr_t src_ptr,
|
||||||
|
size_t count,
|
||||||
|
size_t *nr_moved);
|
||||||
|
|
||||||
|
extern kern_status_t address_space_memmove_v(
|
||||||
|
struct address_space *dest_space,
|
||||||
|
size_t dest_offset,
|
||||||
|
const kern_iovec_t *dest_iov,
|
||||||
|
size_t nr_dest_iov,
|
||||||
|
struct address_space *src_space,
|
||||||
|
size_t src_offset,
|
||||||
|
const kern_iovec_t *src_iov,
|
||||||
|
size_t nr_src_iov,
|
||||||
|
size_t bytes_to_move,
|
||||||
|
size_t *nr_bytes_moved);
|
||||||
|
|
||||||
|
void address_space_dump(struct address_space *region);
|
||||||
|
|
||||||
|
DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base)
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -37,7 +37,7 @@ extern kern_status_t channel_read_msg(
|
|||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
msgid_t msg,
|
msgid_t msg,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
struct vm_region *dest_region,
|
struct address_space *dest_region,
|
||||||
const kern_iovec_t *dest_iov,
|
const kern_iovec_t *dest_iov,
|
||||||
size_t dest_iov_count,
|
size_t dest_iov_count,
|
||||||
size_t *nr_read);
|
size_t *nr_read);
|
||||||
@@ -45,7 +45,7 @@ extern kern_status_t channel_write_msg(
|
|||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
msgid_t msg,
|
msgid_t msg,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
struct vm_region *src_region,
|
struct address_space *src_region,
|
||||||
const kern_iovec_t *src_iov,
|
const kern_iovec_t *src_iov,
|
||||||
size_t src_iov_count,
|
size_t src_iov_count,
|
||||||
size_t *nr_written);
|
size_t *nr_written);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ typedef uintptr_t handle_flags_t;
|
|||||||
|
|
||||||
struct task;
|
struct task;
|
||||||
struct object;
|
struct object;
|
||||||
struct vm_region;
|
struct address_space;
|
||||||
struct handle_list;
|
struct handle_list;
|
||||||
|
|
||||||
struct handle {
|
struct handle {
|
||||||
@@ -57,11 +57,11 @@ extern struct handle *handle_table_get_handle(
|
|||||||
kern_handle_t handle);
|
kern_handle_t handle);
|
||||||
|
|
||||||
extern kern_status_t handle_table_transfer(
|
extern kern_status_t handle_table_transfer(
|
||||||
struct vm_region *dst_region,
|
struct address_space *dst_region,
|
||||||
struct handle_table *dst,
|
struct handle_table *dst,
|
||||||
kern_msg_handle_t *dst_handles,
|
kern_msg_handle_t *dst_handles,
|
||||||
size_t dst_handles_max,
|
size_t dst_handles_max,
|
||||||
struct vm_region *src_region,
|
struct address_space *src_region,
|
||||||
struct handle_table *src,
|
struct handle_table *src,
|
||||||
kern_msg_handle_t *src_handles,
|
kern_msg_handle_t *src_handles,
|
||||||
size_t src_handles_count);
|
size_t src_handles_count);
|
||||||
|
|||||||
@@ -4,10 +4,12 @@
|
|||||||
#include <mango/types.h>
|
#include <mango/types.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct address_space;
|
||||||
|
|
||||||
struct iovec_iterator {
|
struct iovec_iterator {
|
||||||
/* if this is set, we are iterating over a list of iovecs stored in
|
/* if this is set, we are iterating over a list of iovecs stored in
|
||||||
* userspace, and must go through this region to retrieve the data. */
|
* userspace, and must go through this region to retrieve the data. */
|
||||||
struct vm_region *it_region;
|
struct address_space *it_region;
|
||||||
const kern_iovec_t *it_vecs;
|
const kern_iovec_t *it_vecs;
|
||||||
size_t it_nr_vecs;
|
size_t it_nr_vecs;
|
||||||
size_t it_vec_ptr;
|
size_t it_vec_ptr;
|
||||||
@@ -22,7 +24,7 @@ extern void iovec_iterator_begin(
|
|||||||
size_t nr_vecs);
|
size_t nr_vecs);
|
||||||
extern void iovec_iterator_begin_user(
|
extern void iovec_iterator_begin_user(
|
||||||
struct iovec_iterator *it,
|
struct iovec_iterator *it,
|
||||||
struct vm_region *address_space,
|
struct address_space *address_space,
|
||||||
const kern_iovec_t *vecs,
|
const kern_iovec_t *vecs,
|
||||||
size_t nr_vecs);
|
size_t nr_vecs);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#ifndef KERNEL_SYSCALL_H_
|
#ifndef KERNEL_SYSCALL_H_
|
||||||
#define KERNEL_SYSCALL_H_
|
#define KERNEL_SYSCALL_H_
|
||||||
|
|
||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/handle.h>
|
#include <kernel/handle.h>
|
||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/status.h>
|
#include <mango/status.h>
|
||||||
#include <mango/syscall.h>
|
#include <mango/syscall.h>
|
||||||
@@ -28,13 +28,13 @@ static inline bool __validate_access(
|
|||||||
vm_prot_t flags)
|
vm_prot_t flags)
|
||||||
{
|
{
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
vm_region_lock_irqsave(task->t_address_space, &irq_flags);
|
address_space_lock_irqsave(task->t_address_space, &irq_flags);
|
||||||
bool result = vm_region_validate_access(
|
bool result = address_space_validate_access(
|
||||||
task->t_address_space,
|
task->t_address_space,
|
||||||
(virt_addr_t)ptr,
|
(virt_addr_t)ptr,
|
||||||
len,
|
len,
|
||||||
flags | VM_PROT_USER);
|
flags | VM_PROT_USER);
|
||||||
vm_region_unlock_irqrestore(task->t_address_space, irq_flags);
|
address_space_unlock_irqrestore(task->t_address_space, irq_flags);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,29 +85,19 @@ extern kern_status_t sys_vm_object_copy(
|
|||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_copied);
|
size_t *nr_copied);
|
||||||
|
|
||||||
extern kern_status_t sys_vm_region_create(
|
extern kern_status_t sys_address_space_read(
|
||||||
kern_handle_t parent,
|
|
||||||
const char *name,
|
|
||||||
size_t name_len,
|
|
||||||
off_t offset,
|
|
||||||
size_t region_len,
|
|
||||||
vm_prot_t prot,
|
|
||||||
kern_handle_t *out,
|
|
||||||
virt_addr_t *out_base_address);
|
|
||||||
extern kern_status_t sys_vm_region_kill(kern_handle_t region);
|
|
||||||
extern kern_status_t sys_vm_region_read(
|
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
void *dst,
|
void *dst,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_read);
|
size_t *nr_read);
|
||||||
extern kern_status_t sys_vm_region_write(
|
extern kern_status_t sys_address_space_write(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
const void *src,
|
const void *src,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_read);
|
size_t *nr_read);
|
||||||
extern kern_status_t sys_vm_region_map_absolute(
|
extern kern_status_t sys_address_space_map(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
virt_addr_t map_address,
|
virt_addr_t map_address,
|
||||||
kern_handle_t object,
|
kern_handle_t object,
|
||||||
@@ -115,21 +105,18 @@ extern kern_status_t sys_vm_region_map_absolute(
|
|||||||
size_t length,
|
size_t length,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out_base_address);
|
virt_addr_t *out_base_address);
|
||||||
extern kern_status_t sys_vm_region_map_relative(
|
extern kern_status_t sys_address_space_unmap(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
off_t region_offset,
|
virt_addr_t base,
|
||||||
kern_handle_t object,
|
|
||||||
off_t object_offset,
|
|
||||||
size_t length,
|
|
||||||
vm_prot_t prot,
|
|
||||||
virt_addr_t *out_base_address);
|
|
||||||
extern kern_status_t sys_vm_region_unmap_absolute(
|
|
||||||
kern_handle_t region,
|
|
||||||
virt_addr_t address,
|
|
||||||
size_t length);
|
size_t length);
|
||||||
extern kern_status_t sys_vm_region_unmap_relative(
|
extern kern_status_t sys_address_space_reserve(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
|
size_t length,
|
||||||
|
virt_addr_t *out_base_address);
|
||||||
|
extern kern_status_t sys_address_space_release(
|
||||||
|
kern_handle_t region,
|
||||||
|
virt_addr_t base,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
extern kern_status_t sys_kern_log(const char *s);
|
extern kern_status_t sys_kern_log(const char *s);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ struct task {
|
|||||||
char t_name[TASK_NAME_MAX];
|
char t_name[TASK_NAME_MAX];
|
||||||
|
|
||||||
pmap_t t_pmap;
|
pmap_t t_pmap;
|
||||||
struct vm_region *t_address_space;
|
struct address_space *t_address_space;
|
||||||
spin_lock_t t_handles_lock;
|
spin_lock_t t_handles_lock;
|
||||||
struct handle_table *t_handles;
|
struct handle_table *t_handles;
|
||||||
struct btree b_channels;
|
struct btree b_channels;
|
||||||
|
|||||||
@@ -1,191 +0,0 @@
|
|||||||
#ifndef KERNEL_VM_REGION_H_
|
|
||||||
#define KERNEL_VM_REGION_H_
|
|
||||||
|
|
||||||
#include <kernel/object.h>
|
|
||||||
#include <kernel/pmap.h>
|
|
||||||
#include <kernel/vm.h>
|
|
||||||
|
|
||||||
#define VM_REGION_NAME_MAX 64
|
|
||||||
#define VM_REGION_COPY_ALL ((size_t)-1)
|
|
||||||
|
|
||||||
struct vm_region;
|
|
||||||
struct vm_object;
|
|
||||||
|
|
||||||
enum vm_region_status {
|
|
||||||
VM_REGION_DEAD = 0,
|
|
||||||
VM_REGION_ONLINE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum vm_region_entry_type {
|
|
||||||
VM_REGION_ENTRY_NONE = 0,
|
|
||||||
VM_REGION_ENTRY_REGION,
|
|
||||||
VM_REGION_ENTRY_MAPPING,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vm_region_entry {
|
|
||||||
union {
|
|
||||||
struct btree_node e_node;
|
|
||||||
/* this entry is only used to queue vm-region objects for
|
|
||||||
* recursive cleanup */
|
|
||||||
struct queue_entry e_entry;
|
|
||||||
};
|
|
||||||
struct vm_region_entry *e_parent;
|
|
||||||
enum vm_region_entry_type e_type;
|
|
||||||
/* absolute address of this entry */
|
|
||||||
virt_addr_t e_address;
|
|
||||||
/* offset in bytes of this entry within its immediate parent. */
|
|
||||||
off_t e_offset;
|
|
||||||
/* size of the entry in bytes */
|
|
||||||
size_t e_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vm_region_mapping {
|
|
||||||
struct vm_region_entry m_entry;
|
|
||||||
struct vm_object *m_object;
|
|
||||||
|
|
||||||
/* used to link to vm_object->vo_mappings */
|
|
||||||
struct queue_entry m_object_entry;
|
|
||||||
|
|
||||||
vm_prot_t m_prot;
|
|
||||||
/* offset in bytes to the start of the object data that was mapped */
|
|
||||||
off_t m_object_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vm_region {
|
|
||||||
struct object vr_base;
|
|
||||||
enum vm_region_status vr_status;
|
|
||||||
struct vm_region_entry vr_entry;
|
|
||||||
|
|
||||||
char vr_name[VM_REGION_NAME_MAX];
|
|
||||||
|
|
||||||
/* btree of struct vm_region_entry.
|
|
||||||
* sibling entries cannot overlap each other, and child entries must
|
|
||||||
* be entirely contained within their immediate parent entry. */
|
|
||||||
struct btree vr_entries;
|
|
||||||
|
|
||||||
/* memory protection restriction mask.
|
|
||||||
* any mapping in this region, or any of its children, cannot use
|
|
||||||
* protection flags that are not set in this mask.
|
|
||||||
* for example, if VM_PROT_EXEC is /not/ set here, no mapping
|
|
||||||
* can be created in this region or any child region with VM_PROT_EXEC
|
|
||||||
* set. */
|
|
||||||
vm_prot_t vr_prot;
|
|
||||||
|
|
||||||
/* the physical address space in which mappings in this region (and
|
|
||||||
* its children) are created */
|
|
||||||
pmap_t vr_pmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern kern_status_t vm_region_type_init(void);
|
|
||||||
extern struct vm_region *vm_region_cast(struct object *obj);
|
|
||||||
|
|
||||||
/* create a new vm-region, optionally within a parent region.
|
|
||||||
* `offset` is the byte offset within the parent region where the new region
|
|
||||||
* should start.
|
|
||||||
* if no parent is specified, `offset` is the absolute virtual address of the
|
|
||||||
* start of the region.
|
|
||||||
* in both cases, `len` is the length of the new region in bytes. */
|
|
||||||
extern kern_status_t vm_region_create(
|
|
||||||
struct vm_region *parent,
|
|
||||||
const char *name,
|
|
||||||
size_t name_len,
|
|
||||||
off_t offset,
|
|
||||||
size_t region_len,
|
|
||||||
vm_prot_t prot,
|
|
||||||
struct vm_region **out);
|
|
||||||
|
|
||||||
/* recursively kills a given region and all of its sub-regions.
|
|
||||||
* when a region is killed, all of its mappings are unmapped, and any further
|
|
||||||
* operations on the region are denied. however, all handles and references to
|
|
||||||
* the region (any any sub-region) remain valid, and no kernel memory is
|
|
||||||
* de-allocated.
|
|
||||||
* the memory used by the vm-region object itself is de-allocated when the last
|
|
||||||
* handle/reference to the object is released.
|
|
||||||
* this function should be called with `region` locked.
|
|
||||||
*/
|
|
||||||
extern kern_status_t vm_region_kill(
|
|
||||||
struct vm_region *region,
|
|
||||||
unsigned long *lock_flags);
|
|
||||||
|
|
||||||
/* map a vm-object into a vm-region.
|
|
||||||
* [region_offset,length] must fall within exactly one region, and cannot span
|
|
||||||
* multiple sibling regions.
|
|
||||||
* if [region_offset,length] falls within a child region, the map operation
|
|
||||||
* will be transparently redirected to the relevant region.
|
|
||||||
* `prot` must be allowed both by the region into which the mapping is being
|
|
||||||
* created AND the vm-object being mapped. */
|
|
||||||
extern kern_status_t vm_region_map_object(
|
|
||||||
struct vm_region *region,
|
|
||||||
off_t region_offset,
|
|
||||||
struct vm_object *object,
|
|
||||||
off_t object_offset,
|
|
||||||
size_t length,
|
|
||||||
vm_prot_t prot,
|
|
||||||
virt_addr_t *out);
|
|
||||||
|
|
||||||
extern kern_status_t vm_region_unmap(
|
|
||||||
struct vm_region *region,
|
|
||||||
off_t region_offset,
|
|
||||||
size_t length);
|
|
||||||
|
|
||||||
extern bool vm_region_validate_access(
|
|
||||||
struct vm_region *region,
|
|
||||||
off_t offset,
|
|
||||||
size_t len,
|
|
||||||
vm_prot_t prot);
|
|
||||||
|
|
||||||
/* find the mapping corresponding to the given virtual address, and page-in the
|
|
||||||
* necessary vm_page to allow the memory access to succeed. if the relevant
|
|
||||||
* vm-object page hasn't been allocated yet, it will be allocated here. */
|
|
||||||
extern kern_status_t vm_region_demand_map(
|
|
||||||
struct vm_region *region,
|
|
||||||
virt_addr_t addr,
|
|
||||||
enum pmap_fault_flags flags);
|
|
||||||
|
|
||||||
/* get the absolute base virtual address of a region within its
|
|
||||||
* parent/ancestors. */
|
|
||||||
extern virt_addr_t vm_region_get_base_address(const struct vm_region *region);
|
|
||||||
|
|
||||||
extern void vm_region_dump(struct vm_region *region);
|
|
||||||
|
|
||||||
/* read data from the user-space area of a vm-region into a kernel-mode buffer
|
|
||||||
*/
|
|
||||||
extern kern_status_t vm_region_read_kernel(
|
|
||||||
struct vm_region *src_region,
|
|
||||||
virt_addr_t src_ptr,
|
|
||||||
size_t count,
|
|
||||||
void *dest,
|
|
||||||
size_t *nr_read);
|
|
||||||
|
|
||||||
/* write data to the user-space area of a vm-region from a kernel-mode buffer
|
|
||||||
*/
|
|
||||||
extern kern_status_t vm_region_write_kernel(
|
|
||||||
struct vm_region *dst_region,
|
|
||||||
virt_addr_t dst_ptr,
|
|
||||||
size_t count,
|
|
||||||
const void *src,
|
|
||||||
size_t *nr_written);
|
|
||||||
|
|
||||||
extern kern_status_t vm_region_memmove(
|
|
||||||
struct vm_region *dest_region,
|
|
||||||
virt_addr_t dest_ptr,
|
|
||||||
struct vm_region *src_region,
|
|
||||||
virt_addr_t src_ptr,
|
|
||||||
size_t count,
|
|
||||||
size_t *nr_moved);
|
|
||||||
|
|
||||||
extern kern_status_t vm_region_memmove_v(
|
|
||||||
struct vm_region *dest_region,
|
|
||||||
size_t dest_offset,
|
|
||||||
const kern_iovec_t *dest,
|
|
||||||
size_t nr_dest,
|
|
||||||
struct vm_region *src_region,
|
|
||||||
size_t src_offset,
|
|
||||||
const kern_iovec_t *src,
|
|
||||||
size_t nr_src,
|
|
||||||
size_t bytes_to_move,
|
|
||||||
size_t *nr_bytes_moved);
|
|
||||||
|
|
||||||
DEFINE_OBJECT_LOCK_FUNCTION(vm_region, vr_base)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -112,7 +112,10 @@ void kernel_init(uintptr_t arg)
|
|||||||
struct task *bootstrap_task = task_create("bootstrap", 9);
|
struct task *bootstrap_task = task_create("bootstrap", 9);
|
||||||
tracek("created bootstrap task (pid=%u)", bootstrap_task->t_id);
|
tracek("created bootstrap task (pid=%u)", bootstrap_task->t_id);
|
||||||
|
|
||||||
bsp_launch_async(&bsp, bootstrap_task);
|
status = bsp_launch_async(&bsp, bootstrap_task);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
printk("bsp launch failed with status %d", status);
|
||||||
|
}
|
||||||
|
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
|
|||||||
116
kernel/bsp.c
116
kernel/bsp.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/bsp.h>
|
#include <kernel/bsp.h>
|
||||||
#include <kernel/handle.h>
|
#include <kernel/handle.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
@@ -6,7 +7,6 @@
|
|||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-object.h>
|
#include <kernel/vm-object.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
#define BOOTSTRAP_STACK_SIZE 0x10000
|
#define BOOTSTRAP_STACK_SIZE 0x10000
|
||||||
|
|
||||||
@@ -71,101 +71,6 @@ kern_status_t bsp_load(struct bsp *bsp, const struct boot_module *mod)
|
|||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static kern_status_t map_executable_dyn(
|
|
||||||
struct bsp *bsp,
|
|
||||||
struct task *task,
|
|
||||||
virt_addr_t *entry)
|
|
||||||
{
|
|
||||||
kern_status_t status = KERN_OK;
|
|
||||||
size_t exec_size = 0;
|
|
||||||
if (bsp->bsp_trailer.bsp_text_vaddr > bsp->bsp_trailer.bsp_data_vaddr) {
|
|
||||||
exec_size = bsp->bsp_trailer.bsp_text_vaddr
|
|
||||||
+ bsp->bsp_trailer.bsp_text_size;
|
|
||||||
} else {
|
|
||||||
exec_size = bsp->bsp_trailer.bsp_data_vaddr
|
|
||||||
+ bsp->bsp_trailer.bsp_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_region *region;
|
|
||||||
status = vm_region_create(
|
|
||||||
task->t_address_space,
|
|
||||||
"exec",
|
|
||||||
4,
|
|
||||||
VM_REGION_ANY_OFFSET,
|
|
||||||
exec_size,
|
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXEC | VM_PROT_USER,
|
|
||||||
®ion);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_object *data = vm_object_create(
|
|
||||||
".data",
|
|
||||||
5,
|
|
||||||
bsp->bsp_trailer.bsp_data_size,
|
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER);
|
|
||||||
if (!data) {
|
|
||||||
return KERN_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
virt_addr_t text_base = 0, data_base = 0;
|
|
||||||
|
|
||||||
off_t text_foffset = bsp->bsp_trailer.bsp_exec_offset
|
|
||||||
+ bsp->bsp_trailer.bsp_text_faddr;
|
|
||||||
off_t data_foffset = 0;
|
|
||||||
off_t text_voffset = bsp->bsp_trailer.bsp_text_vaddr;
|
|
||||||
off_t data_voffset = bsp->bsp_trailer.bsp_data_vaddr;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
size_t tmp = 0;
|
|
||||||
status = vm_object_copy(
|
|
||||||
data,
|
|
||||||
0,
|
|
||||||
bsp->bsp_vmo,
|
|
||||||
bsp->bsp_trailer.bsp_data_faddr,
|
|
||||||
bsp->bsp_trailer.bsp_data_size,
|
|
||||||
&tmp);
|
|
||||||
|
|
||||||
tracek("read %zuB of data from executable", tmp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tracek("text_foffset=%06llx, data_foffset=%06llx",
|
|
||||||
text_foffset,
|
|
||||||
data_foffset);
|
|
||||||
tracek("text_voffset=%08llx, data_voffset=%08llx",
|
|
||||||
text_voffset,
|
|
||||||
data_voffset);
|
|
||||||
|
|
||||||
status = vm_region_map_object(
|
|
||||||
region,
|
|
||||||
text_voffset,
|
|
||||||
bsp->bsp_vmo,
|
|
||||||
text_foffset,
|
|
||||||
bsp->bsp_trailer.bsp_text_size,
|
|
||||||
VM_PROT_READ | VM_PROT_EXEC | VM_PROT_USER,
|
|
||||||
&text_base);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = vm_region_map_object(
|
|
||||||
region,
|
|
||||||
data_voffset,
|
|
||||||
data,
|
|
||||||
data_foffset,
|
|
||||||
bsp->bsp_trailer.bsp_data_size,
|
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
|
||||||
&data_base);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
tracek("text_base=%08llx, data_base=%08llx", text_base, data_base);
|
|
||||||
|
|
||||||
*entry = text_base + bsp->bsp_trailer.bsp_exec_entry;
|
|
||||||
return KERN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static kern_status_t map_executable_exec(
|
static kern_status_t map_executable_exec(
|
||||||
struct bsp *bsp,
|
struct bsp *bsp,
|
||||||
struct task *task,
|
struct task *task,
|
||||||
@@ -189,9 +94,6 @@ static kern_status_t map_executable_exec(
|
|||||||
off_t text_voffset = bsp->bsp_trailer.bsp_text_vaddr;
|
off_t text_voffset = bsp->bsp_trailer.bsp_text_vaddr;
|
||||||
off_t data_voffset = bsp->bsp_trailer.bsp_data_vaddr;
|
off_t data_voffset = bsp->bsp_trailer.bsp_data_vaddr;
|
||||||
|
|
||||||
text_voffset -= vm_region_get_base_address(task->t_address_space);
|
|
||||||
data_voffset -= vm_region_get_base_address(task->t_address_space);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
size_t tmp = 0;
|
size_t tmp = 0;
|
||||||
status = vm_object_copy(
|
status = vm_object_copy(
|
||||||
@@ -212,7 +114,7 @@ static kern_status_t map_executable_exec(
|
|||||||
text_voffset,
|
text_voffset,
|
||||||
data_voffset);
|
data_voffset);
|
||||||
|
|
||||||
status = vm_region_map_object(
|
status = address_space_map(
|
||||||
task->t_address_space,
|
task->t_address_space,
|
||||||
text_voffset,
|
text_voffset,
|
||||||
bsp->bsp_vmo,
|
bsp->bsp_vmo,
|
||||||
@@ -224,7 +126,7 @@ static kern_status_t map_executable_exec(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = vm_region_map_object(
|
status = address_space_map(
|
||||||
task->t_address_space,
|
task->t_address_space,
|
||||||
data_voffset,
|
data_voffset,
|
||||||
data,
|
data,
|
||||||
@@ -257,9 +159,9 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
return KERN_NO_ENTRY;
|
return KERN_NO_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = vm_region_map_object(
|
status = address_space_map(
|
||||||
task->t_address_space,
|
task->t_address_space,
|
||||||
VM_REGION_ANY_OFFSET,
|
MAP_ADDRESS_ANY,
|
||||||
user_stack,
|
user_stack,
|
||||||
0,
|
0,
|
||||||
BOOTSTRAP_STACK_SIZE,
|
BOOTSTRAP_STACK_SIZE,
|
||||||
@@ -270,9 +172,9 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = vm_region_map_object(
|
status = address_space_map(
|
||||||
task->t_address_space,
|
task->t_address_space,
|
||||||
VM_REGION_ANY_OFFSET,
|
MAP_ADDRESS_ANY,
|
||||||
bsp->bsp_vmo,
|
bsp->bsp_vmo,
|
||||||
0,
|
0,
|
||||||
bsp->bsp_trailer.bsp_exec_offset,
|
bsp->bsp_trailer.bsp_exec_offset,
|
||||||
@@ -288,7 +190,7 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
vm_region_dump(task->t_address_space);
|
address_space_dump(task->t_address_space);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sp = stack_buffer + BOOTSTRAP_STACK_SIZE;
|
sp = stack_buffer + BOOTSTRAP_STACK_SIZE;
|
||||||
@@ -298,7 +200,7 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
task_open_handle(task, &task->t_base, 0, &self);
|
task_open_handle(task, &task->t_base, 0, &self);
|
||||||
task_open_handle(
|
task_open_handle(
|
||||||
task,
|
task,
|
||||||
&task->t_address_space->vr_base,
|
&task->t_address_space->s_base,
|
||||||
0,
|
0,
|
||||||
&self_address_space);
|
&self_address_space);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/channel.h>
|
#include <kernel/channel.h>
|
||||||
#include <kernel/msg.h>
|
#include <kernel/msg.h>
|
||||||
#include <kernel/port.h>
|
#include <kernel/port.h>
|
||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
#include <mango/signal.h>
|
#include <mango/signal.h>
|
||||||
|
|
||||||
#define CHANNEL_CAST(p) OBJECT_C_CAST(struct channel, c_base, &channel_type, p)
|
#define CHANNEL_CAST(p) OBJECT_C_CAST(struct channel, c_base, &channel_type, p)
|
||||||
@@ -167,13 +167,13 @@ extern kern_status_t channel_recv_msg(
|
|||||||
struct task *sender = msg->msg_sender_thread->tr_parent;
|
struct task *sender = msg->msg_sender_thread->tr_parent;
|
||||||
struct task *receiver = self->tr_parent;
|
struct task *receiver = self->tr_parent;
|
||||||
|
|
||||||
struct vm_region *src = sender->t_address_space,
|
struct address_space *src = sender->t_address_space,
|
||||||
*dst = receiver->t_address_space;
|
*dst = receiver->t_address_space;
|
||||||
|
|
||||||
unsigned long f;
|
unsigned long f;
|
||||||
vm_region_lock_pair_irqsave(src, dst, &f);
|
address_space_lock_pair_irqsave(src, dst, &f);
|
||||||
|
|
||||||
kern_status_t status = vm_region_memmove_v(
|
kern_status_t status = address_space_memmove_v(
|
||||||
dst,
|
dst,
|
||||||
0,
|
0,
|
||||||
out_msg->msg_data,
|
out_msg->msg_data,
|
||||||
@@ -182,7 +182,7 @@ extern kern_status_t channel_recv_msg(
|
|||||||
0,
|
0,
|
||||||
msg->msg_req.msg_data,
|
msg->msg_req.msg_data,
|
||||||
msg->msg_req.msg_data_count,
|
msg->msg_req.msg_data_count,
|
||||||
VM_REGION_COPY_ALL,
|
ADDRESS_SPACE_COPY_ALL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
@@ -210,7 +210,7 @@ extern kern_status_t channel_recv_msg(
|
|||||||
&sender->t_handles_lock,
|
&sender->t_handles_lock,
|
||||||
&receiver->t_handles_lock,
|
&receiver->t_handles_lock,
|
||||||
f);
|
f);
|
||||||
vm_region_unlock_pair_irqrestore(src, dst, f);
|
address_space_unlock_pair_irqrestore(src, dst, f);
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
kmsg_reply_error(msg, status, &msg_lock_flags);
|
kmsg_reply_error(msg, status, &msg_lock_flags);
|
||||||
@@ -250,12 +250,12 @@ extern kern_status_t channel_reply_msg(
|
|||||||
/* the task that is about to send the response */
|
/* the task that is about to send the response */
|
||||||
struct task *sender = self->tr_parent;
|
struct task *sender = self->tr_parent;
|
||||||
|
|
||||||
struct vm_region *src = sender->t_address_space,
|
struct address_space *src = sender->t_address_space,
|
||||||
*dst = receiver->t_address_space;
|
*dst = receiver->t_address_space;
|
||||||
unsigned long f;
|
unsigned long f;
|
||||||
vm_region_lock_pair_irqsave(src, dst, &f);
|
address_space_lock_pair_irqsave(src, dst, &f);
|
||||||
|
|
||||||
kern_status_t status = vm_region_memmove_v(
|
kern_status_t status = address_space_memmove_v(
|
||||||
dst,
|
dst,
|
||||||
0,
|
0,
|
||||||
msg->msg_resp.msg_data,
|
msg->msg_resp.msg_data,
|
||||||
@@ -264,7 +264,7 @@ extern kern_status_t channel_reply_msg(
|
|||||||
0,
|
0,
|
||||||
reply->msg_data,
|
reply->msg_data,
|
||||||
reply->msg_data_count,
|
reply->msg_data_count,
|
||||||
VM_REGION_COPY_ALL,
|
ADDRESS_SPACE_COPY_ALL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
@@ -292,7 +292,7 @@ extern kern_status_t channel_reply_msg(
|
|||||||
&sender->t_handles_lock,
|
&sender->t_handles_lock,
|
||||||
&receiver->t_handles_lock,
|
&receiver->t_handles_lock,
|
||||||
f);
|
f);
|
||||||
vm_region_unlock_pair_irqrestore(src, dst, f);
|
address_space_unlock_pair_irqrestore(src, dst, f);
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
kmsg_reply_error(msg, status, &msg_lock_flags);
|
kmsg_reply_error(msg, status, &msg_lock_flags);
|
||||||
@@ -308,7 +308,7 @@ extern kern_status_t channel_read_msg(
|
|||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
msgid_t id,
|
msgid_t id,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
struct vm_region *dest_region,
|
struct address_space *dest_region,
|
||||||
const kern_iovec_t *dest_iov,
|
const kern_iovec_t *dest_iov,
|
||||||
size_t dest_iov_count,
|
size_t dest_iov_count,
|
||||||
size_t *nr_read)
|
size_t *nr_read)
|
||||||
@@ -325,13 +325,13 @@ extern kern_status_t channel_read_msg(
|
|||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *src_region
|
struct address_space *src_region
|
||||||
= msg->msg_sender_thread->tr_parent->t_address_space;
|
= msg->msg_sender_thread->tr_parent->t_address_space;
|
||||||
|
|
||||||
unsigned long f;
|
unsigned long f;
|
||||||
vm_region_lock_pair_irqsave(src_region, dest_region, &f);
|
address_space_lock_pair_irqsave(src_region, dest_region, &f);
|
||||||
|
|
||||||
kern_status_t status = vm_region_memmove_v(
|
kern_status_t status = address_space_memmove_v(
|
||||||
dest_region,
|
dest_region,
|
||||||
0,
|
0,
|
||||||
dest_iov,
|
dest_iov,
|
||||||
@@ -340,9 +340,9 @@ extern kern_status_t channel_read_msg(
|
|||||||
offset,
|
offset,
|
||||||
msg->msg_req.msg_data,
|
msg->msg_req.msg_data,
|
||||||
msg->msg_req.msg_data_count,
|
msg->msg_req.msg_data_count,
|
||||||
VM_REGION_COPY_ALL,
|
ADDRESS_SPACE_COPY_ALL,
|
||||||
nr_read);
|
nr_read);
|
||||||
vm_region_unlock_pair_irqrestore(src_region, dest_region, f);
|
address_space_unlock_pair_irqrestore(src_region, dest_region, f);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
|
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ extern kern_status_t channel_write_msg(
|
|||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
msgid_t id,
|
msgid_t id,
|
||||||
size_t offset,
|
size_t offset,
|
||||||
struct vm_region *src_region,
|
struct address_space *src_region,
|
||||||
const kern_iovec_t *src_iov,
|
const kern_iovec_t *src_iov,
|
||||||
size_t src_iov_count,
|
size_t src_iov_count,
|
||||||
size_t *nr_written)
|
size_t *nr_written)
|
||||||
@@ -370,13 +370,13 @@ extern kern_status_t channel_write_msg(
|
|||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *dest_region
|
struct address_space *dest_region
|
||||||
= msg->msg_sender_thread->tr_parent->t_address_space;
|
= msg->msg_sender_thread->tr_parent->t_address_space;
|
||||||
|
|
||||||
unsigned long f;
|
unsigned long f;
|
||||||
vm_region_lock_pair_irqsave(src_region, dest_region, &f);
|
address_space_lock_pair_irqsave(src_region, dest_region, &f);
|
||||||
|
|
||||||
kern_status_t status = vm_region_memmove_v(
|
kern_status_t status = address_space_memmove_v(
|
||||||
dest_region,
|
dest_region,
|
||||||
offset,
|
offset,
|
||||||
msg->msg_resp.msg_data,
|
msg->msg_resp.msg_data,
|
||||||
@@ -385,9 +385,9 @@ extern kern_status_t channel_write_msg(
|
|||||||
0,
|
0,
|
||||||
src_iov,
|
src_iov,
|
||||||
src_iov_count,
|
src_iov_count,
|
||||||
VM_REGION_COPY_ALL,
|
ADDRESS_SPACE_COPY_ALL,
|
||||||
nr_written);
|
nr_written);
|
||||||
vm_region_unlock_pair_irqrestore(src_region, dest_region, f);
|
address_space_unlock_pair_irqrestore(src_region, dest_region, f);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
|
spin_unlock_irqrestore(&msg->msg_lock, msg_lock_flags);
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/handle.h>
|
#include <kernel/handle.h>
|
||||||
#include <kernel/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <kernel/object.h>
|
#include <kernel/object.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
#include <mango/types.h>
|
#include <mango/types.h>
|
||||||
|
|
||||||
@@ -195,11 +195,11 @@ struct handle *handle_table_get_handle(
|
|||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t handle_table_transfer(
|
kern_status_t handle_table_transfer(
|
||||||
struct vm_region *dst_region,
|
struct address_space *dst_region,
|
||||||
struct handle_table *dst,
|
struct handle_table *dst,
|
||||||
kern_msg_handle_t *dst_handles,
|
kern_msg_handle_t *dst_handles,
|
||||||
size_t dst_handles_max,
|
size_t dst_handles_max,
|
||||||
struct vm_region *src_region,
|
struct address_space *src_region,
|
||||||
struct handle_table *src,
|
struct handle_table *src,
|
||||||
kern_msg_handle_t *src_handles,
|
kern_msg_handle_t *src_handles,
|
||||||
size_t src_handles_count)
|
size_t src_handles_count)
|
||||||
@@ -214,7 +214,7 @@ kern_status_t handle_table_transfer(
|
|||||||
= (virt_addr_t)src_handles + (i * sizeof src_handle);
|
= (virt_addr_t)src_handles + (i * sizeof src_handle);
|
||||||
virt_addr_t dst_handle_addr
|
virt_addr_t dst_handle_addr
|
||||||
= (virt_addr_t)dst_handles + (i * sizeof dst_handle);
|
= (virt_addr_t)dst_handles + (i * sizeof dst_handle);
|
||||||
status = vm_region_read_kernel(
|
status = address_space_read(
|
||||||
src_region,
|
src_region,
|
||||||
src_handle_addr,
|
src_handle_addr,
|
||||||
sizeof src_handle,
|
sizeof src_handle,
|
||||||
@@ -223,7 +223,7 @@ kern_status_t handle_table_transfer(
|
|||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
src_handle.hnd_result = KERN_OK;
|
src_handle.hnd_result = KERN_OK;
|
||||||
vm_region_write_kernel(
|
address_space_write(
|
||||||
src_region,
|
src_region,
|
||||||
src_handle_addr,
|
src_handle_addr,
|
||||||
sizeof src_handle,
|
sizeof src_handle,
|
||||||
@@ -244,7 +244,7 @@ kern_status_t handle_table_transfer(
|
|||||||
if (!src_entry) {
|
if (!src_entry) {
|
||||||
status = KERN_INVALID_ARGUMENT;
|
status = KERN_INVALID_ARGUMENT;
|
||||||
src_handle.hnd_result = KERN_INVALID_ARGUMENT;
|
src_handle.hnd_result = KERN_INVALID_ARGUMENT;
|
||||||
vm_region_write_kernel(
|
address_space_write(
|
||||||
src_region,
|
src_region,
|
||||||
src_handle_addr,
|
src_handle_addr,
|
||||||
sizeof src_handle,
|
sizeof src_handle,
|
||||||
@@ -299,13 +299,13 @@ kern_status_t handle_table_transfer(
|
|||||||
|
|
||||||
src_handle.hnd_result = status;
|
src_handle.hnd_result = status;
|
||||||
|
|
||||||
vm_region_write_kernel(
|
address_space_write(
|
||||||
src_region,
|
src_region,
|
||||||
src_handle_addr,
|
src_handle_addr,
|
||||||
sizeof src_handle,
|
sizeof src_handle,
|
||||||
&src_handle,
|
&src_handle,
|
||||||
NULL);
|
NULL);
|
||||||
vm_region_write_kernel(
|
address_space_write(
|
||||||
dst_region,
|
dst_region,
|
||||||
dst_handle_addr,
|
dst_handle_addr,
|
||||||
sizeof dst_handle,
|
sizeof dst_handle,
|
||||||
@@ -317,7 +317,7 @@ kern_status_t handle_table_transfer(
|
|||||||
kern_msg_handle_t handle = {0};
|
kern_msg_handle_t handle = {0};
|
||||||
virt_addr_t handle_addr
|
virt_addr_t handle_addr
|
||||||
= (virt_addr_t)src_handles + (i * sizeof handle);
|
= (virt_addr_t)src_handles + (i * sizeof handle);
|
||||||
vm_region_read_kernel(
|
address_space_read(
|
||||||
src_region,
|
src_region,
|
||||||
handle_addr,
|
handle_addr,
|
||||||
sizeof handle,
|
sizeof handle,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/iovec.h>
|
#include <kernel/iovec.h>
|
||||||
#include <kernel/libc/string.h>
|
#include <kernel/libc/string.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
static bool read_iovec(
|
static bool read_iovec(
|
||||||
struct iovec_iterator *it,
|
struct iovec_iterator *it,
|
||||||
@@ -18,7 +18,7 @@ static bool read_iovec(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t nr_read = 0;
|
size_t nr_read = 0;
|
||||||
kern_status_t status = vm_region_read_kernel(
|
kern_status_t status = address_space_read(
|
||||||
it->it_region,
|
it->it_region,
|
||||||
(virt_addr_t)it->it_vecs + (index * sizeof(kern_iovec_t)),
|
(virt_addr_t)it->it_vecs + (index * sizeof(kern_iovec_t)),
|
||||||
sizeof(kern_iovec_t),
|
sizeof(kern_iovec_t),
|
||||||
@@ -30,7 +30,7 @@ static bool read_iovec(
|
|||||||
|
|
||||||
void iovec_iterator_begin_user(
|
void iovec_iterator_begin_user(
|
||||||
struct iovec_iterator *it,
|
struct iovec_iterator *it,
|
||||||
struct vm_region *region,
|
struct address_space *region,
|
||||||
const kern_iovec_t *vecs,
|
const kern_iovec_t *vecs,
|
||||||
size_t nr_vecs)
|
size_t nr_vecs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,14 +68,12 @@ SYSCALL_GATE vm_object_read SYS_VM_OBJECT_READ 5
|
|||||||
SYSCALL_GATE vm_object_write SYS_VM_OBJECT_WRITE 5
|
SYSCALL_GATE vm_object_write SYS_VM_OBJECT_WRITE 5
|
||||||
SYSCALL_GATE vm_object_copy SYS_VM_OBJECT_COPY 6
|
SYSCALL_GATE vm_object_copy SYS_VM_OBJECT_COPY 6
|
||||||
|
|
||||||
SYSCALL_GATE vm_region_create SYS_VM_REGION_CREATE 8
|
SYSCALL_GATE address_space_read SYS_ADDRESS_SPACE_READ 5
|
||||||
SYSCALL_GATE vm_region_kill SYS_VM_REGION_KILL 1
|
SYSCALL_GATE address_space_write SYS_ADDRESS_SPACE_WRITE 5
|
||||||
SYSCALL_GATE vm_region_read SYS_VM_REGION_READ 5
|
SYSCALL_GATE address_space_map SYS_ADDRESS_SPACE_MAP 7
|
||||||
SYSCALL_GATE vm_region_write SYS_VM_REGION_WRITE 5
|
SYSCALL_GATE address_space_unmap SYS_ADDRESS_SPACE_UNMAP 3
|
||||||
SYSCALL_GATE vm_region_map_absolute SYS_VM_REGION_MAP_ABSOLUTE 7
|
SYSCALL_GATE address_space_reserve SYS_ADDRESS_SPACE_RESERVE 4
|
||||||
SYSCALL_GATE vm_region_map_relative SYS_VM_REGION_MAP_RELATIVE 7
|
SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
|
||||||
SYSCALL_GATE vm_region_unmap_absolute SYS_VM_REGION_UNMAP_ABSOLUTE 3
|
|
||||||
SYSCALL_GATE vm_region_unmap_relative SYS_VM_REGION_UNMAP_RELATIVE 3
|
|
||||||
|
|
||||||
SYSCALL_GATE kern_log SYS_KERN_LOG 1
|
SYSCALL_GATE kern_log SYS_KERN_LOG 1
|
||||||
SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1
|
SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1
|
||||||
|
|||||||
@@ -30,29 +30,19 @@ extern kern_status_t vm_object_copy(
|
|||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_copied);
|
size_t *nr_copied);
|
||||||
|
|
||||||
extern kern_status_t vm_region_create(
|
extern kern_status_t address_space_read(
|
||||||
kern_handle_t parent,
|
|
||||||
const char *name,
|
|
||||||
size_t name_len,
|
|
||||||
off_t offset,
|
|
||||||
size_t region_len,
|
|
||||||
vm_prot_t prot,
|
|
||||||
kern_handle_t *out,
|
|
||||||
virt_addr_t *out_base_address);
|
|
||||||
extern kern_status_t vm_region_kill(kern_handle_t region);
|
|
||||||
extern kern_status_t vm_region_read(
|
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
void *dst,
|
void *dst,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_read);
|
size_t *nr_read);
|
||||||
extern kern_status_t vm_region_write(
|
extern kern_status_t address_space_write(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
const void *src,
|
const void *src,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_read);
|
size_t *nr_read);
|
||||||
extern kern_status_t vm_region_map_absolute(
|
extern kern_status_t address_space_map(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
virt_addr_t map_address,
|
virt_addr_t map_address,
|
||||||
kern_handle_t object,
|
kern_handle_t object,
|
||||||
@@ -60,21 +50,18 @@ extern kern_status_t vm_region_map_absolute(
|
|||||||
size_t length,
|
size_t length,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out_base_address);
|
virt_addr_t *out_base_address);
|
||||||
extern kern_status_t vm_region_map_relative(
|
extern kern_status_t address_space_unmap(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
off_t region_offset,
|
virt_addr_t base,
|
||||||
kern_handle_t object,
|
|
||||||
off_t object_offset,
|
|
||||||
size_t length,
|
|
||||||
vm_prot_t prot,
|
|
||||||
virt_addr_t *out_base_address);
|
|
||||||
extern kern_status_t vm_region_unmap_absolute(
|
|
||||||
kern_handle_t region,
|
|
||||||
virt_addr_t address,
|
|
||||||
size_t length);
|
size_t length);
|
||||||
extern kern_status_t vm_region_unmap_relative(
|
extern kern_status_t address_space_reserve(
|
||||||
kern_handle_t region,
|
kern_handle_t region,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
|
size_t length,
|
||||||
|
virt_addr_t *out_base_address);
|
||||||
|
extern kern_status_t address_space_release(
|
||||||
|
kern_handle_t region,
|
||||||
|
virt_addr_t base,
|
||||||
size_t length);
|
size_t length);
|
||||||
|
|
||||||
extern kern_status_t vm_controller_create(kern_handle_t *out);
|
extern kern_status_t vm_controller_create(kern_handle_t *out);
|
||||||
|
|||||||
@@ -17,14 +17,12 @@
|
|||||||
#define SYS_VM_OBJECT_READ 0x0Du
|
#define SYS_VM_OBJECT_READ 0x0Du
|
||||||
#define SYS_VM_OBJECT_WRITE 0x0Eu
|
#define SYS_VM_OBJECT_WRITE 0x0Eu
|
||||||
#define SYS_VM_OBJECT_COPY 0x0Fu
|
#define SYS_VM_OBJECT_COPY 0x0Fu
|
||||||
#define SYS_VM_REGION_CREATE 0x10u
|
#define SYS_ADDRESS_SPACE_READ 0x12u
|
||||||
#define SYS_VM_REGION_KILL 0x11u
|
#define SYS_ADDRESS_SPACE_WRITE 0x13u
|
||||||
#define SYS_VM_REGION_READ 0x12u
|
#define SYS_ADDRESS_SPACE_MAP 0x14u
|
||||||
#define SYS_VM_REGION_WRITE 0x13u
|
#define SYS_ADDRESS_SPACE_UNMAP 0x15u
|
||||||
#define SYS_VM_REGION_MAP_ABSOLUTE 0x14u
|
#define SYS_ADDRESS_SPACE_RESERVE 0x16u
|
||||||
#define SYS_VM_REGION_MAP_RELATIVE 0x15u
|
#define SYS_ADDRESS_SPACE_RELEASE 0x17u
|
||||||
#define SYS_VM_REGION_UNMAP_ABSOLUTE 0x16u
|
|
||||||
#define SYS_VM_REGION_UNMAP_RELATIVE 0x17u
|
|
||||||
#define SYS_MSG_SEND 0x18u
|
#define SYS_MSG_SEND 0x18u
|
||||||
#define SYS_MSG_RECV 0x19u
|
#define SYS_MSG_RECV 0x19u
|
||||||
#define SYS_MSG_REPLY 0x1Au
|
#define SYS_MSG_REPLY 0x1Au
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
#define VM_PROT_NOCACHE 0x10u
|
#define VM_PROT_NOCACHE 0x10u
|
||||||
#define VM_PROT_MAP_SPECIFIC 0x40u
|
#define VM_PROT_MAP_SPECIFIC 0x40u
|
||||||
|
|
||||||
#define VM_REGION_ANY_OFFSET ((off_t) - 1)
|
#define MAP_ADDRESS_ANY ((virt_addr_t) - 1)
|
||||||
|
#define MAP_ADDRESS_INVALID ((virt_addr_t)0)
|
||||||
#define KERN_HANDLE_INVALID ((kern_handle_t)0xFFFFFFFF)
|
#define KERN_HANDLE_INVALID ((kern_handle_t)0xFFFFFFFF)
|
||||||
|
|
||||||
#define KERN_CFG_INVALID 0x00u
|
#define KERN_CFG_INVALID 0x00u
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
extern kern_status_t setup_kernel_task(void);
|
extern kern_status_t setup_kernel_task(void);
|
||||||
extern kern_status_t setup_idle_task(void);
|
extern kern_status_t setup_idle_task(void);
|
||||||
|
|||||||
21
sched/task.c
21
sched/task.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/channel.h>
|
#include <kernel/channel.h>
|
||||||
#include <kernel/clock.h>
|
#include <kernel/clock.h>
|
||||||
#include <kernel/cpu.h>
|
#include <kernel/cpu.h>
|
||||||
@@ -10,7 +11,6 @@
|
|||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
#define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p)
|
#define TASK_CAST(p) OBJECT_C_CAST(struct task, t_base, &task_type, p)
|
||||||
|
|
||||||
@@ -95,15 +95,6 @@ kern_status_t setup_kernel_task(void)
|
|||||||
__kernel_task->t_state = TASK_RUNNING;
|
__kernel_task->t_state = TASK_RUNNING;
|
||||||
__kernel_task->t_pmap = get_kernel_pmap();
|
__kernel_task->t_pmap = get_kernel_pmap();
|
||||||
|
|
||||||
vm_region_create(
|
|
||||||
NULL,
|
|
||||||
"root",
|
|
||||||
4,
|
|
||||||
VM_KERNEL_BASE,
|
|
||||||
VM_KERNEL_LIMIT - VM_KERNEL_BASE,
|
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXEC | VM_PROT_SVR,
|
|
||||||
&__kernel_task->t_address_space);
|
|
||||||
|
|
||||||
snprintf(
|
snprintf(
|
||||||
__kernel_task->t_name,
|
__kernel_task->t_name,
|
||||||
sizeof __kernel_task->t_name,
|
sizeof __kernel_task->t_name,
|
||||||
@@ -195,16 +186,12 @@ struct task *task_create(const char *name, size_t name_len)
|
|||||||
|
|
||||||
task->t_id = pid_alloc();
|
task->t_id = pid_alloc();
|
||||||
task->t_pmap = pmap;
|
task->t_pmap = pmap;
|
||||||
vm_region_create(
|
address_space_create(
|
||||||
NULL,
|
|
||||||
"root",
|
|
||||||
4,
|
|
||||||
VM_USER_BASE,
|
VM_USER_BASE,
|
||||||
VM_USER_LIMIT - VM_USER_BASE,
|
VM_USER_LIMIT,
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXEC | VM_PROT_USER,
|
|
||||||
&task->t_address_space);
|
&task->t_address_space);
|
||||||
|
|
||||||
task->t_address_space->vr_pmap = pmap;
|
task->t_address_space->s_pmap = pmap;
|
||||||
task->t_state = TASK_RUNNING;
|
task->t_state = TASK_RUNNING;
|
||||||
task->t_handles = handle_table_create();
|
task->t_handles = handle_table_create();
|
||||||
|
|
||||||
|
|||||||
@@ -1,134 +1,13 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/vm-object.h>
|
#include <kernel/vm-object.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
kern_status_t sys_vm_region_create(
|
kern_status_t sys_address_space_read(
|
||||||
kern_handle_t parent,
|
|
||||||
const char *name,
|
|
||||||
size_t name_len,
|
|
||||||
off_t offset,
|
|
||||||
size_t region_len,
|
|
||||||
vm_prot_t prot,
|
|
||||||
kern_handle_t *out,
|
|
||||||
virt_addr_t *out_base_address)
|
|
||||||
{
|
|
||||||
struct task *self = current_task();
|
|
||||||
|
|
||||||
if (name_len && !validate_access_r(self, name, name_len)) {
|
|
||||||
return KERN_MEMORY_FAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validate_access_w(self, out, sizeof *out)) {
|
|
||||||
return KERN_MEMORY_FAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validate_access_w(
|
|
||||||
self,
|
|
||||||
out_base_address,
|
|
||||||
sizeof *out_base_address)) {
|
|
||||||
return KERN_MEMORY_FAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long flags;
|
|
||||||
task_lock_irqsave(self, &flags);
|
|
||||||
|
|
||||||
struct object *obj = NULL;
|
|
||||||
handle_flags_t handle_flags = 0;
|
|
||||||
kern_status_t status
|
|
||||||
= task_resolve_handle(self, parent, &obj, &handle_flags);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_region *parent_region = vm_region_cast(obj);
|
|
||||||
if (!parent_region) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return KERN_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct handle *child_handle_slot = NULL;
|
|
||||||
kern_handle_t child_handle = KERN_HANDLE_INVALID;
|
|
||||||
|
|
||||||
status = handle_table_alloc_handle(
|
|
||||||
self->t_handles,
|
|
||||||
&child_handle_slot,
|
|
||||||
&child_handle);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
vm_region_lock_irqsave(parent_region, &flags);
|
|
||||||
|
|
||||||
struct vm_region *child = NULL;
|
|
||||||
status = vm_region_create(
|
|
||||||
parent_region,
|
|
||||||
name,
|
|
||||||
name_len,
|
|
||||||
offset,
|
|
||||||
region_len,
|
|
||||||
prot,
|
|
||||||
&child);
|
|
||||||
vm_region_unlock_irqrestore(parent_region, flags);
|
|
||||||
object_unref(obj);
|
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_lock_irqsave(self, &flags);
|
|
||||||
handle_table_free_handle(self->t_handles, child_handle);
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
child_handle_slot->h_object = &child->vr_base;
|
|
||||||
object_add_handle(&child->vr_base);
|
|
||||||
object_unref(&child->vr_base);
|
|
||||||
|
|
||||||
*out = child_handle;
|
|
||||||
*out_base_address = vm_region_get_base_address(child);
|
|
||||||
|
|
||||||
return KERN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
kern_status_t sys_vm_region_kill(kern_handle_t region_handle)
|
|
||||||
{
|
|
||||||
struct task *self = current_task();
|
|
||||||
|
|
||||||
unsigned long flags;
|
|
||||||
task_lock_irqsave(self, &flags);
|
|
||||||
|
|
||||||
struct object *obj = NULL;
|
|
||||||
handle_flags_t handle_flags = 0;
|
|
||||||
kern_status_t status
|
|
||||||
= task_resolve_handle(self, region_handle, &obj, &handle_flags);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(obj);
|
|
||||||
if (!region) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return KERN_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
|
|
||||||
vm_region_lock_irqsave(region, &flags);
|
|
||||||
status = vm_region_kill(region, &flags);
|
|
||||||
vm_region_unlock_irqrestore(region, flags);
|
|
||||||
object_unref(obj);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
kern_status_t sys_vm_region_read(
|
|
||||||
kern_handle_t region_handle,
|
kern_handle_t region_handle,
|
||||||
void *dst,
|
void *dst,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_read)
|
size_t *nr_read)
|
||||||
{
|
{
|
||||||
@@ -154,7 +33,7 @@ kern_status_t sys_vm_region_read(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(obj);
|
struct address_space *region = address_space_cast(obj);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
@@ -162,23 +41,25 @@ kern_status_t sys_vm_region_read(
|
|||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
virt_addr_t src_address = vm_region_get_base_address(region) + offset;
|
address_space_lock_irqsave(region, &flags);
|
||||||
status = vm_region_memmove(
|
status = address_space_memmove(
|
||||||
self->t_address_space,
|
self->t_address_space,
|
||||||
(virt_addr_t)dst,
|
(virt_addr_t)dst,
|
||||||
region,
|
region,
|
||||||
src_address,
|
base,
|
||||||
count,
|
count,
|
||||||
nr_read);
|
nr_read);
|
||||||
|
address_space_unlock_irqrestore(region, flags);
|
||||||
|
|
||||||
object_unref(obj);
|
object_unref(obj);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t sys_vm_region_write(
|
kern_status_t sys_address_space_write(
|
||||||
kern_handle_t region_handle,
|
kern_handle_t region_handle,
|
||||||
const void *src,
|
const void *src,
|
||||||
off_t offset,
|
virt_addr_t base,
|
||||||
size_t count,
|
size_t count,
|
||||||
size_t *nr_written)
|
size_t *nr_written)
|
||||||
{
|
{
|
||||||
@@ -205,7 +86,7 @@ kern_status_t sys_vm_region_write(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(obj);
|
struct address_space *region = address_space_cast(obj);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
@@ -213,20 +94,22 @@ kern_status_t sys_vm_region_write(
|
|||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
virt_addr_t dst_address = vm_region_get_base_address(region) + offset;
|
address_space_lock_irqsave(region, &flags);
|
||||||
status = vm_region_memmove(
|
status = address_space_memmove(
|
||||||
region,
|
region,
|
||||||
dst_address,
|
base,
|
||||||
self->t_address_space,
|
self->t_address_space,
|
||||||
(virt_addr_t)src,
|
(virt_addr_t)src,
|
||||||
count,
|
count,
|
||||||
nr_written);
|
nr_written);
|
||||||
|
address_space_unlock_irqrestore(region, flags);
|
||||||
|
|
||||||
object_unref(obj);
|
object_unref(obj);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t sys_vm_region_map_absolute(
|
kern_status_t sys_address_space_map(
|
||||||
kern_handle_t region_handle,
|
kern_handle_t region_handle,
|
||||||
virt_addr_t map_address,
|
virt_addr_t map_address,
|
||||||
kern_handle_t object_handle,
|
kern_handle_t object_handle,
|
||||||
@@ -267,7 +150,7 @@ kern_status_t sys_vm_region_map_absolute(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(region_obj);
|
struct address_space *region = address_space_cast(region_obj);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
@@ -280,21 +163,17 @@ kern_status_t sys_vm_region_map_absolute(
|
|||||||
}
|
}
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
|
address_space_lock_irqsave(region, &flags);
|
||||||
off_t region_offset = VM_REGION_ANY_OFFSET;
|
/* address_space_map will take care of locking `vmo` */
|
||||||
if (map_address != VM_REGION_ANY_OFFSET) {
|
status = address_space_map(
|
||||||
region_offset
|
|
||||||
= map_address - vm_region_get_base_address(region);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = vm_region_map_object(
|
|
||||||
region,
|
region,
|
||||||
region_offset,
|
map_address,
|
||||||
vmo,
|
vmo,
|
||||||
object_offset,
|
object_offset,
|
||||||
length,
|
length,
|
||||||
prot,
|
prot,
|
||||||
out_base_address);
|
out_base_address);
|
||||||
|
address_space_unlock_irqrestore(region, flags);
|
||||||
|
|
||||||
object_unref(vmo_obj);
|
object_unref(vmo_obj);
|
||||||
object_unref(region_obj);
|
object_unref(region_obj);
|
||||||
@@ -302,23 +181,50 @@ kern_status_t sys_vm_region_map_absolute(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t sys_vm_region_map_relative(
|
kern_status_t sys_address_space_unmap(
|
||||||
kern_handle_t region_handle,
|
kern_handle_t region_handle,
|
||||||
off_t region_offset,
|
virt_addr_t base,
|
||||||
kern_handle_t object_handle,
|
size_t length)
|
||||||
off_t object_offset,
|
{
|
||||||
|
struct task *self = current_task();
|
||||||
|
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
unsigned long flags;
|
||||||
|
task_lock_irqsave(self, &flags);
|
||||||
|
|
||||||
|
struct object *region_obj = NULL;
|
||||||
|
handle_flags_t region_flags = 0;
|
||||||
|
status = task_resolve_handle(
|
||||||
|
self,
|
||||||
|
region_handle,
|
||||||
|
®ion_obj,
|
||||||
|
®ion_flags);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct address_space *region = address_space_cast(region_obj);
|
||||||
|
if (!region) {
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
return KERN_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
|
status = address_space_unmap(region, base, length);
|
||||||
|
|
||||||
|
object_unref(region_obj);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t sys_address_space_reserve(
|
||||||
|
kern_handle_t region_handle,
|
||||||
|
virt_addr_t map_address,
|
||||||
size_t length,
|
size_t length,
|
||||||
vm_prot_t prot,
|
|
||||||
virt_addr_t *out_base_address)
|
virt_addr_t *out_base_address)
|
||||||
{
|
{
|
||||||
tracek("vm_region_map_relative(%x, %x, %x, %x, %x, %x, %p)",
|
|
||||||
region_handle,
|
|
||||||
region_offset,
|
|
||||||
object_handle,
|
|
||||||
object_offset,
|
|
||||||
length,
|
|
||||||
prot,
|
|
||||||
out_base_address);
|
|
||||||
struct task *self = current_task();
|
struct task *self = current_task();
|
||||||
|
|
||||||
if (out_base_address
|
if (out_base_address
|
||||||
@@ -333,8 +239,8 @@ kern_status_t sys_vm_region_map_relative(
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
task_lock_irqsave(self, &flags);
|
task_lock_irqsave(self, &flags);
|
||||||
|
|
||||||
struct object *region_obj = NULL, *vmo_obj = NULL;
|
struct object *region_obj = NULL;
|
||||||
handle_flags_t region_flags = 0, vmo_flags = 0;
|
handle_flags_t region_flags = 0;
|
||||||
status = task_resolve_handle(
|
status = task_resolve_handle(
|
||||||
self,
|
self,
|
||||||
region_handle,
|
region_handle,
|
||||||
@@ -345,45 +251,30 @@ kern_status_t sys_vm_region_map_relative(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = task_resolve_handle(self, object_handle, &vmo_obj, &vmo_flags);
|
struct address_space *region = address_space_cast(region_obj);
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(region_obj);
|
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_object *vmo = vm_object_cast(vmo_obj);
|
|
||||||
if (!vmo) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return KERN_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
status = vm_region_map_object(
|
address_space_lock_irqsave(region, &flags);
|
||||||
|
status = address_space_reserve(
|
||||||
region,
|
region,
|
||||||
region_offset,
|
map_address,
|
||||||
vmo,
|
|
||||||
object_offset,
|
|
||||||
length,
|
length,
|
||||||
prot,
|
|
||||||
out_base_address);
|
out_base_address);
|
||||||
|
address_space_unlock_irqrestore(region, flags);
|
||||||
|
|
||||||
object_unref(vmo_obj);
|
|
||||||
object_unref(region_obj);
|
object_unref(region_obj);
|
||||||
|
|
||||||
tracek("result: %u", status);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t sys_vm_region_unmap_absolute(
|
kern_status_t sys_address_space_release(
|
||||||
kern_handle_t region_handle,
|
kern_handle_t region_handle,
|
||||||
virt_addr_t address,
|
virt_addr_t base,
|
||||||
size_t length)
|
size_t length)
|
||||||
{
|
{
|
||||||
struct task *self = current_task();
|
struct task *self = current_task();
|
||||||
@@ -404,7 +295,7 @@ kern_status_t sys_vm_region_unmap_absolute(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(region_obj);
|
struct address_space *region = address_space_cast(region_obj);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
@@ -412,46 +303,9 @@ kern_status_t sys_vm_region_unmap_absolute(
|
|||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
|
|
||||||
off_t region_offset = address - vm_region_get_base_address(region);
|
address_space_lock_irqsave(region, &flags);
|
||||||
status = vm_region_unmap(region, region_offset, length);
|
status = address_space_unmap(region, base, length);
|
||||||
|
address_space_unlock_irqrestore(region, flags);
|
||||||
object_unref(region_obj);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
kern_status_t sys_vm_region_unmap_relative(
|
|
||||||
kern_handle_t region_handle,
|
|
||||||
off_t offset,
|
|
||||||
size_t length)
|
|
||||||
{
|
|
||||||
struct task *self = current_task();
|
|
||||||
|
|
||||||
kern_status_t status = KERN_OK;
|
|
||||||
unsigned long flags;
|
|
||||||
task_lock_irqsave(self, &flags);
|
|
||||||
|
|
||||||
struct object *region_obj = NULL;
|
|
||||||
handle_flags_t region_flags = 0;
|
|
||||||
status = task_resolve_handle(
|
|
||||||
self,
|
|
||||||
region_handle,
|
|
||||||
®ion_obj,
|
|
||||||
®ion_flags);
|
|
||||||
if (status != KERN_OK) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vm_region *region = vm_region_cast(region_obj);
|
|
||||||
if (!region) {
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
return KERN_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
|
||||||
|
|
||||||
status = vm_region_unmap(region, offset, length);
|
|
||||||
|
|
||||||
object_unref(region_obj);
|
object_unref(region_obj);
|
||||||
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
kern_status_t sys_kern_config_get(kern_config_key_t key, void *ptr, size_t len)
|
kern_status_t sys_kern_config_get(kern_config_key_t key, void *ptr, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,14 +15,12 @@ static const virt_addr_t syscall_table[] = {
|
|||||||
SYSCALL_TABLE_ENTRY(VM_OBJECT_READ, vm_object_read),
|
SYSCALL_TABLE_ENTRY(VM_OBJECT_READ, vm_object_read),
|
||||||
SYSCALL_TABLE_ENTRY(VM_OBJECT_WRITE, vm_object_write),
|
SYSCALL_TABLE_ENTRY(VM_OBJECT_WRITE, vm_object_write),
|
||||||
SYSCALL_TABLE_ENTRY(VM_OBJECT_COPY, vm_object_copy),
|
SYSCALL_TABLE_ENTRY(VM_OBJECT_COPY, vm_object_copy),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_CREATE, vm_region_create),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_READ, address_space_read),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_KILL, vm_region_kill),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_WRITE, address_space_write),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_READ, vm_region_read),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_MAP, address_space_map),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_WRITE, vm_region_write),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_UNMAP, address_space_unmap),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_MAP_ABSOLUTE, vm_region_map_absolute),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RESERVE, address_space_reserve),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_MAP_RELATIVE, vm_region_map_relative),
|
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RELEASE, address_space_release),
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_UNMAP_ABSOLUTE, vm_region_unmap_absolute),
|
|
||||||
SYSCALL_TABLE_ENTRY(VM_REGION_UNMAP_RELATIVE, vm_region_unmap_relative),
|
|
||||||
SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log),
|
SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log),
|
||||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close),
|
SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close),
|
||||||
SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get),
|
SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get),
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
|
kern_status_t sys_channel_create(unsigned int id, kern_handle_t *out)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/task.h>
|
#include <kernel/task.h>
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
extern kern_status_t sys_task_exit(int status)
|
extern kern_status_t sys_task_exit(int status)
|
||||||
{
|
{
|
||||||
@@ -128,10 +128,10 @@ kern_status_t sys_task_create(
|
|||||||
task_unlock_irqrestore(parent, flags);
|
task_unlock_irqrestore(parent, flags);
|
||||||
|
|
||||||
child_handle_slot->h_object = &child->t_base;
|
child_handle_slot->h_object = &child->t_base;
|
||||||
space_handle_slot->h_object = &child->t_address_space->vr_base;
|
space_handle_slot->h_object = &child->t_address_space->s_base;
|
||||||
|
|
||||||
object_add_handle(&child->t_base);
|
object_add_handle(&child->t_base);
|
||||||
object_add_handle(&child->t_address_space->vr_base);
|
object_add_handle(&child->t_address_space->s_base);
|
||||||
|
|
||||||
object_unref(parent_obj);
|
object_unref(parent_obj);
|
||||||
|
|
||||||
@@ -252,8 +252,8 @@ kern_status_t sys_task_get_address_space(
|
|||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_slot->h_object = &task->t_address_space->vr_base;
|
handle_slot->h_object = &task->t_address_space->s_base;
|
||||||
object_add_handle(&task->t_address_space->vr_base);
|
object_add_handle(&task->t_address_space->s_base);
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, flags);
|
||||||
object_unref(task_obj);
|
object_unref(task_obj);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/vm-object.h>
|
#include <kernel/vm-object.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
|
|
||||||
kern_status_t sys_vm_object_create(
|
kern_status_t sys_vm_object_create(
|
||||||
const char *name,
|
const char *name,
|
||||||
|
|||||||
1341
vm/address-space.c
Normal file
1341
vm/address-space.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,12 @@
|
|||||||
#include <limits.h>
|
#include <kernel/address-space.h>
|
||||||
#include <kernel/machine/cpu.h>
|
#include <kernel/machine/cpu.h>
|
||||||
#include <kernel/memblock.h>
|
#include <kernel/memblock.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <mango/status.h>
|
#include <kernel/vm-controller.h>
|
||||||
#include <kernel/vm-object.h>
|
#include <kernel/vm-object.h>
|
||||||
#include <kernel/vm-region.h>
|
|
||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <mango/status.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -42,7 +43,8 @@ kern_status_t vm_bootstrap(
|
|||||||
|
|
||||||
kmalloc_init();
|
kmalloc_init();
|
||||||
vm_object_type_init();
|
vm_object_type_init();
|
||||||
vm_region_type_init();
|
vm_controller_type_init();
|
||||||
|
address_space_type_init();
|
||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1927
vm/vm-region.c
1927
vm/vm-region.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user