Implemented BeOS compatible create_area()/delete_area() calls for the VM
that will call the internal vm_*() calls. This will make it easier to just drop in another VM. Also (partially - Ingo was faster) introduced the new syscall naming scheme _kern_ & _user_ prefixes to them into the system namespace, and no longer clobber the application namespace. Removed the now unused user_vm_create_anonymous_region() call. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4311 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3c39df3d0b
commit
20fcd813b9
@ -460,39 +460,10 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
region_id user_vm_create_anonymous_region(char *uname, void **uaddress, int addr_type,
|
||||
addr size, int wiring, int lock)
|
||||
{
|
||||
char name[SYS_MAX_OS_NAME_LEN];
|
||||
void *address;
|
||||
int rc, rc2;
|
||||
|
||||
if((addr)uname >= KERNEL_BASE && (addr)uname <= KERNEL_TOP)
|
||||
return ERR_VM_BAD_USER_MEMORY;
|
||||
|
||||
rc = user_strncpy(name, uname, SYS_MAX_OS_NAME_LEN-1);
|
||||
if(rc < 0)
|
||||
return rc;
|
||||
name[SYS_MAX_OS_NAME_LEN-1] = 0;
|
||||
|
||||
rc = user_memcpy(&address, uaddress, sizeof(address));
|
||||
if(rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = vm_create_anonymous_region(vm_get_current_user_aspace_id(), name, &address, addr_type, size, wiring, lock);
|
||||
if(rc < 0)
|
||||
return rc;
|
||||
|
||||
rc2 = user_memcpy(uaddress, &address, sizeof(address));
|
||||
if(rc2 < 0)
|
||||
return rc2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
region_id vm_create_anonymous_region(aspace_id aid, char *name, void **address,
|
||||
int addr_type, addr size, int wiring,
|
||||
int lock)
|
||||
region_id
|
||||
vm_create_anonymous_region(aspace_id aid, const char *name, void **address,
|
||||
int addr_type, addr size, int wiring, int lock)
|
||||
{
|
||||
int err;
|
||||
vm_region *region;
|
||||
@ -516,10 +487,6 @@ region_id vm_create_anonymous_region(aspace_id aid, char *name, void **address,
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
aspace = vm_get_aspace_by_id(aid);
|
||||
if(aspace == NULL)
|
||||
return ERR_VM_INVALID_ASPACE;
|
||||
|
||||
aspace = vm_get_aspace_by_id(aid);
|
||||
if(aspace == NULL)
|
||||
return ERR_VM_INVALID_ASPACE;
|
||||
@ -2147,9 +2114,9 @@ static int vm_soft_fault(addr address, bool is_write, bool is_user)
|
||||
|
||||
TRACE;
|
||||
|
||||
if(err == 0) {
|
||||
if (err == 0) {
|
||||
int new_lock = region->lock;
|
||||
if(page->cache_ref != top_cache_ref && !is_write)
|
||||
if (page->cache_ref != top_cache_ref && !is_write)
|
||||
new_lock &= ~LOCK_RW;
|
||||
|
||||
atomic_add(&page->ref_count, 1);
|
||||
@ -2255,3 +2222,171 @@ int user_memset(void *s, char c, size_t count)
|
||||
return arch_cpu_user_memset(s, c, count, &thread_get_current_thread()->fault_handler);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
area_id
|
||||
create_area_etc(struct team *team, char *name, void **address, uint32 addressSpec,
|
||||
uint32 size, uint32 lock, uint32 protection)
|
||||
{
|
||||
switch (addressSpec) {
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_ANY_ADDRESS:
|
||||
addressSpec = REGION_ADDR_ANY_ADDRESS;
|
||||
break;
|
||||
case B_EXACT_KERNEL_ADDRESS:
|
||||
case B_EXACT_ADDRESS:
|
||||
addressSpec = REGION_ADDR_EXACT_ADDRESS;
|
||||
break;
|
||||
case B_BASE_ADDRESS:
|
||||
dprintf("create_area: B_BASE_ADDRESS demanded (switch to B_ANY_ADDRESS)!\n");
|
||||
addressSpec = REGION_ADDR_ANY_ADDRESS;
|
||||
break;
|
||||
default:
|
||||
dprintf("create_area: invalid address spec!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// create_area() "protection" is vm_create_anonymous_region() "lock"
|
||||
protection = PROTECTION_TO_LOCK(protection);
|
||||
|
||||
// create_area() "lock" is vm_create_anonymous_region() "wiring"
|
||||
switch (lock) {
|
||||
case B_ALREADY_WIRED:
|
||||
lock = REGION_WIRING_WIRED_ALREADY;
|
||||
break;
|
||||
case B_LOMEM:
|
||||
dprintf("create_area: asked for B_LOMEM - unsupported (switch to B_FULL_LOCK)!\n");
|
||||
case B_FULL_LOCK:
|
||||
case B_LAZY_LOCK: // ToDo: lazy lock is not supported by the VM yet
|
||||
lock = REGION_WIRING_WIRED;
|
||||
break;
|
||||
case B_CONTIGUOUS:
|
||||
lock = REGION_WIRING_WIRED_CONTIG;
|
||||
break;
|
||||
case B_NO_LOCK:
|
||||
lock = REGION_WIRING_WIRED_CONTIG;
|
||||
break;
|
||||
default:
|
||||
dprintf("create_area: invalid locking mode!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return vm_create_anonymous_region(team->_aspace_id, (char *)name, address,
|
||||
addressSpec, size, lock, protection);
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
create_area(const char *name, void **address, uint32 addressSpec, size_t size, uint32 lock,
|
||||
uint32 protection)
|
||||
{
|
||||
aspace_id areaSpace;
|
||||
|
||||
switch (addressSpec) {
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_EXACT_KERNEL_ADDRESS:
|
||||
areaSpace = vm_get_kernel_aspace_id();
|
||||
break;
|
||||
default:
|
||||
areaSpace = vm_get_current_user_aspace_id();
|
||||
break;
|
||||
}
|
||||
switch (addressSpec) {
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_ANY_ADDRESS:
|
||||
addressSpec = REGION_ADDR_ANY_ADDRESS;
|
||||
break;
|
||||
case B_EXACT_KERNEL_ADDRESS:
|
||||
case B_EXACT_ADDRESS:
|
||||
addressSpec = REGION_ADDR_EXACT_ADDRESS;
|
||||
break;
|
||||
case B_BASE_ADDRESS:
|
||||
dprintf("create_area: B_BASE_ADDRESS demanded (switch to B_ANY_ADDRESS)!\n");
|
||||
addressSpec = REGION_ADDR_ANY_ADDRESS;
|
||||
break;
|
||||
default:
|
||||
dprintf("create_area: invalid address spec!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// create_area() "protection" is vm_create_anonymous_region() "lock"
|
||||
protection = PROTECTION_TO_LOCK(protection);
|
||||
|
||||
// create_area() "lock" is vm_create_anonymous_region() "wiring"
|
||||
switch (lock) {
|
||||
case B_ALREADY_WIRED:
|
||||
lock = REGION_WIRING_WIRED_ALREADY;
|
||||
break;
|
||||
case B_LOMEM:
|
||||
dprintf("create_area: asked for B_LOMEM - unsupported (switch to B_FULL_LOCK)!\n");
|
||||
case B_FULL_LOCK:
|
||||
case B_LAZY_LOCK: // ToDo: lazy lock is not supported by the VM yet
|
||||
lock = REGION_WIRING_WIRED;
|
||||
break;
|
||||
case B_CONTIGUOUS:
|
||||
lock = REGION_WIRING_WIRED_CONTIG;
|
||||
break;
|
||||
case B_NO_LOCK:
|
||||
lock = REGION_WIRING_WIRED_CONTIG;
|
||||
break;
|
||||
default:
|
||||
dprintf("create_area: invalid locking mode!\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return vm_create_anonymous_region(areaSpace, (char *)name, address,
|
||||
addressSpec, size, lock, protection);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
delete_area(area_id area)
|
||||
{
|
||||
// ToDo: works only correctly for kernel areas!
|
||||
return vm_delete_region(vm_get_kernel_aspace_id(), area);
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
_user_create_area(const char *userName, void **userAddress, uint32 addressSpec, size_t size, uint32 lock,
|
||||
uint32 protection)
|
||||
{
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
area_id area;
|
||||
void *address;
|
||||
|
||||
// filter out some unavailable values (for userland)
|
||||
switch (addressSpec) {
|
||||
case B_ANY_KERNEL_ADDRESS:
|
||||
case B_EXACT_KERNEL_ADDRESS:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
if (protection & B_KERNEL_PROTECTION)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!CHECK_USER_ADDRESS(userName)
|
||||
|| !CHECK_USER_ADDRESS(userAddress)
|
||||
|| user_strlcpy(name, userName, sizeof(name)) < B_OK
|
||||
|| user_memcpy(&address, userAddress, sizeof(address)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
area = create_area(name, &address, addressSpec, size, lock, protection);
|
||||
|
||||
if (area >= B_OK && user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
|
||||
// ToDo: shouldn't I delete the area here?
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_delete_area(area_id area)
|
||||
{
|
||||
// ToDo: works only correctly if the area belongs to the caller!
|
||||
return vm_delete_region(vm_get_current_user_aspace_id(), area);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user