diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2009-11-28 17:37:54 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2009-11-28 17:37:54 +0100 |
commit | d088a062c1dcbd5047a6bf41ccb2cb1da2c78060 (patch) | |
tree | 8754ffd902b553ca3e95486d3ee6fba4d3c2ec46 | |
parent | 43347f8e5f17cf246d2199b4db5b899e8bb08557 (diff) |
Add memory object proxies
Memory object proxies permit to replicate objects with different parameters,
like reduced privileged, different offset, etc. They are e.g. essential for
properly managing memory access permissions.
2005-06-06 Marcus Brinkmann <marcus@gnu.org>
* include/mach/mach4.defs: Add memory_object_create_proxy
interface.
* Makefile.in (vm-cfiles): Add memory_object_proxy.c.
* i386/include/mach/i386/vm_types.h (vm_offset_array_t): New type.
* include/mach/memory_object.h (memory_object_array_t): New type.
* vm/memory_object_proxy.c: New file.
* kern/ipc_kobject.h: New macro IKOT_PAGER_PROXY. Bump up macros
IKOT_UNKNOWN and IKOT_MAX_TYPE.
* kern/ipc_kobject.c (ipc_kobject_notify): Call
memory_object_proxy_notify for IKOT_PAGER_PROXY.
* vm/vm_init.c (vm_mem_init): Call memory_object_proxy_init.
* vm/vm_user.c (vm_map): Implement support for proxy memory
objects.
-rw-r--r-- | Makefrag.am | 1 | ||||
-rw-r--r-- | i386/include/mach/i386/vm_types.h | 1 | ||||
-rw-r--r-- | include/mach/mach4.defs | 30 | ||||
-rw-r--r-- | include/mach/memory_object.h | 3 | ||||
-rw-r--r-- | kern/ipc_kobject.c | 3 | ||||
-rw-r--r-- | kern/ipc_kobject.h | 5 | ||||
-rw-r--r-- | vm/vm_init.c | 1 | ||||
-rw-r--r-- | vm/vm_user.c | 23 |
8 files changed, 64 insertions, 3 deletions
diff --git a/Makefrag.am b/Makefrag.am index bf5b593..05aaeb4 100644 --- a/Makefrag.am +++ b/Makefrag.am @@ -215,6 +215,7 @@ libkernel_a_SOURCES += \ # libkernel_a_SOURCES += \ + vm/memory_object_proxy.c \ vm/memory_object.c \ vm/memory_object.h \ vm/pmap.h \ diff --git a/i386/include/mach/i386/vm_types.h b/i386/include/mach/i386/vm_types.h index 7fb1bcb..d54008e 100644 --- a/i386/include/mach/i386/vm_types.h +++ b/i386/include/mach/i386/vm_types.h @@ -74,6 +74,7 @@ typedef unsigned int uint32; * e.g. an offset into a virtual memory space. */ typedef natural_t vm_offset_t; +typedef vm_offset_t * vm_offset_array_t; /* * A vm_size_t is the proper type for e.g. diff --git a/include/mach/mach4.defs b/include/mach/mach4.defs index e4f363f..114edf4 100644 --- a/include/mach/mach4.defs +++ b/include/mach/mach4.defs @@ -79,4 +79,34 @@ skip /* pc_sampling reserved 1*/; skip /* pc_sampling reserved 2*/; skip /* pc_sampling reserved 3*/; skip /* pc_sampling reserved 4*/; + +#else + +skip; /* task_enable_pc_sampling */ +skip; /* task_disable_pc_sampling */ +skip; /* task_get_sampled_pcs */ +skip; /* thread_enable_pc_sampling */ +skip; /* thread_disable_pc_sampling */ +skip; /* thread_get_sampled_pcs */ + +skip /* pc_sampling reserved 1*/; +skip /* pc_sampling reserved 2*/; +skip /* pc_sampling reserved 3*/; +skip /* pc_sampling reserved 4*/; + #endif + + +/* Create a new proxy memory object from [START;START+LEN) in the + given OBJECT at OFFSET in the new object with the maximum + protection MAX_PROTECTION and return it in *PORT. */ +type vm_offset_array_t = array[*:1024] of vm_offset_t; +routine memory_object_create_proxy( + task : ipc_space_t; + max_protection : vm_prot_t; + object : memory_object_array_t = + array[*:1024] of memory_object_t; + offset : vm_offset_array_t; + start : vm_offset_array_t; + len : vm_offset_array_t; + out proxy : mach_port_t); diff --git a/include/mach/memory_object.h b/include/mach/memory_object.h index b4dd71f..f281f04 100644 --- a/include/mach/memory_object.h +++ b/include/mach/memory_object.h @@ -46,6 +46,9 @@ typedef mach_port_t memory_object_t; /* the object to map; used by the */ /* kernel to retrieve or store data */ +typedef mach_port_t * memory_object_array_t; + /* should be memory_object_t * */ + typedef mach_port_t memory_object_control_t; /* Provided to a memory manager; ... */ /* used to control a memory object */ diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c index 959cc0d..3d8775b 100644 --- a/kern/ipc_kobject.c +++ b/kern/ipc_kobject.c @@ -355,6 +355,9 @@ ipc_kobject_notify(request_header, reply_header) case IKOT_DEVICE: return ds_notify(request_header); + case IKOT_PAGER_PROXY: + return memory_object_proxy_notify(request_header); + default: return FALSE; } diff --git a/kern/ipc_kobject.h b/kern/ipc_kobject.h index 7ffa99f..cb79574 100644 --- a/kern/ipc_kobject.h +++ b/kern/ipc_kobject.h @@ -77,9 +77,10 @@ typedef unsigned int ipc_kobject_type_t; #define IKOT_LOCK_SET 24 #define IKOT_CLOCK 25 #define IKOT_CLOCK_CTRL 26 +#define IKOT_PAGER_PROXY 27 /* << new entries here */ -#define IKOT_UNKNOWN 27 /* magic catchall */ -#define IKOT_MAX_TYPE 28 /* # of IKOT_ types */ +#define IKOT_UNKNOWN 28 /* magic catchall */ +#define IKOT_MAX_TYPE 29 /* # of IKOT_ types */ /* Please keep ipc/ipc_object.c:ikot_print_array up to date */ #define is_ipc_kobject(ikot) (ikot != IKOT_NONE) diff --git a/vm/vm_init.c b/vm/vm_init.c index 06317ac..f6a4060 100644 --- a/vm/vm_init.c +++ b/vm/vm_init.c @@ -82,4 +82,5 @@ void vm_mem_bootstrap() void vm_mem_init() { vm_object_init(); + memory_object_proxy_init(); } diff --git a/vm/vm_user.c b/vm/vm_user.c index 813b100..672daab 100644 --- a/vm/vm_user.c +++ b/vm/vm_user.c @@ -276,6 +276,12 @@ kern_return_t vm_copy(map, source_address, size, dest_address) return KERN_SUCCESS; } + +/* XXX From memory_object_proxy.c */ +kern_return_t +memory_object_proxy_lookup (ipc_port_t proxy_object, ipc_port_t *object, + vm_prot_t *max_protection); + /* * Routine: vm_map */ @@ -325,7 +331,22 @@ kern_return_t vm_map( copy = FALSE; } else if ((object = vm_object_enter(memory_object, size, FALSE)) == VM_OBJECT_NULL) - return(KERN_INVALID_ARGUMENT); + { + ipc_port_t real_memobj; + vm_prot_t prot; + result = memory_object_proxy_lookup (memory_object, &real_memobj, + &prot); + if (result != KERN_SUCCESS) + return result; + + /* Reduce the allowed access to the memory object. */ + max_protection &= prot; + cur_protection &= prot; + + if ((object = vm_object_enter(real_memobj, size, FALSE)) + == VM_OBJECT_NULL) + return KERN_INVALID_ARGUMENT; + } /* * Perform the copy if requested |