This commit is contained in:
parent
7293d47bf0
commit
84c1ac4cee
@ -94,13 +94,14 @@ AddressSpace& AddressSpace::operator=(AddressSpace&& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<u64> AddressSpace::alloc_region(usize count, int prot, int flags, u64 shmid, bool persistent)
|
Result<u64> AddressSpace::alloc_region(usize count, int prot, int flags, off_t offset, u64 shmid, bool persistent)
|
||||||
{
|
{
|
||||||
auto update_region = [=](VMRegion* region) {
|
auto update_region = [=](VMRegion* region) {
|
||||||
region->used = true;
|
region->used = true;
|
||||||
region->persistent = persistent;
|
region->persistent = persistent;
|
||||||
region->prot = prot;
|
region->prot = prot;
|
||||||
region->flags = flags;
|
region->flags = flags;
|
||||||
|
region->offset = offset;
|
||||||
region->shmid = shmid;
|
region->shmid = shmid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ Result<u64> AddressSpace::alloc_region(usize count, int prot, int flags, u64 shm
|
|||||||
return err(ENOMEM);
|
return err(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<bool> AddressSpace::set_region(u64 address, usize count, bool used, int prot, int flags, u64 shmid,
|
Result<bool> AddressSpace::set_region(u64 address, usize count, bool used, int prot, int flags, off_t offset, u64 shmid,
|
||||||
bool persistent)
|
bool persistent)
|
||||||
{
|
{
|
||||||
if (address >= VM_END) return err(EINVAL);
|
if (address >= VM_END) return err(EINVAL);
|
||||||
@ -143,6 +144,7 @@ Result<bool> AddressSpace::set_region(u64 address, usize count, bool used, int p
|
|||||||
region->persistent = persistent;
|
region->persistent = persistent;
|
||||||
region->prot = prot;
|
region->prot = prot;
|
||||||
region->flags = flags;
|
region->flags = flags;
|
||||||
|
region->offset = offset;
|
||||||
region->shmid = shmid;
|
region->shmid = shmid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -200,6 +202,23 @@ Result<bool> AddressSpace::set_region(u64 address, usize count, bool used, int p
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> AddressSpace::sync_regions(u64 address, usize count)
|
||||||
|
{
|
||||||
|
if (address >= VM_END) return err(EINVAL);
|
||||||
|
|
||||||
|
u64 end = address + (count * ARCH_PAGE_SIZE);
|
||||||
|
|
||||||
|
for (auto* region : m_regions)
|
||||||
|
{
|
||||||
|
if (region->end < address) continue;
|
||||||
|
if (region->start > end) return {};
|
||||||
|
|
||||||
|
region->sync_shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void AddressSpace::merge_contiguous_regions(VMRegion* a, VMRegion* b)
|
void AddressSpace::merge_contiguous_regions(VMRegion* a, VMRegion* b)
|
||||||
{
|
{
|
||||||
a->end = b->end;
|
a->end = b->end;
|
||||||
@ -279,3 +298,12 @@ void VMRegion::cleanup_shared()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VMRegion::sync_shared()
|
||||||
|
{
|
||||||
|
if (used && (flags & MAP_SHARED) && (prot & PROT_WRITE))
|
||||||
|
{
|
||||||
|
SharedMemory* shmem = g_shared_memory_map.try_get_ref(shmid);
|
||||||
|
if (shmem) { shmem->inode->write((const u8*)start, offset, count * ARCH_PAGE_SIZE); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <luna/LinkedList.h>
|
#include <luna/LinkedList.h>
|
||||||
#include <luna/OwnedPtr.h>
|
#include <luna/OwnedPtr.h>
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
class VMRegion : LinkedListNode<VMRegion>
|
class VMRegion : LinkedListNode<VMRegion>
|
||||||
{
|
{
|
||||||
@ -15,8 +16,10 @@ class VMRegion : LinkedListNode<VMRegion>
|
|||||||
int flags { 0 };
|
int flags { 0 };
|
||||||
int prot { 0 };
|
int prot { 0 };
|
||||||
u64 shmid;
|
u64 shmid;
|
||||||
|
off_t offset { 0 };
|
||||||
|
|
||||||
void cleanup_shared();
|
void cleanup_shared();
|
||||||
|
void sync_shared();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddressSpace
|
class AddressSpace
|
||||||
@ -27,19 +30,21 @@ class AddressSpace
|
|||||||
|
|
||||||
AddressSpace& operator=(AddressSpace&& other);
|
AddressSpace& operator=(AddressSpace&& other);
|
||||||
|
|
||||||
Result<u64> alloc_region(usize count, int prot, int flags, u64 shmid = 0, bool persistent = false);
|
Result<u64> alloc_region(usize count, int prot, int flags, off_t offset, u64 shmid = 0, bool persistent = false);
|
||||||
|
|
||||||
Result<bool> test_and_alloc_region(u64 address, usize count, int prot, int flags, u64 shmid = 0,
|
Result<bool> test_and_alloc_region(u64 address, usize count, int prot, int flags, off_t offset, u64 shmid = 0,
|
||||||
bool persistent = false)
|
bool persistent = false)
|
||||||
{
|
{
|
||||||
return set_region(address, count, true, prot, flags, shmid, persistent);
|
return set_region(address, count, true, prot, flags, offset, shmid, persistent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<bool> free_region(u64 address, usize count)
|
Result<bool> free_region(u64 address, usize count)
|
||||||
{
|
{
|
||||||
return set_region(address, count, false, 0, 0, 0, false);
|
return set_region(address, count, false, 0, 0, 0, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<void> sync_regions(u64 address, usize count);
|
||||||
|
|
||||||
static Result<OwnedPtr<AddressSpace>> try_create();
|
static Result<OwnedPtr<AddressSpace>> try_create();
|
||||||
|
|
||||||
Result<OwnedPtr<AddressSpace>> clone();
|
Result<OwnedPtr<AddressSpace>> clone();
|
||||||
@ -50,7 +55,8 @@ class AddressSpace
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result<bool> set_region(u64 address, usize count, bool used, int prot, int flags, u64 shmid, bool persistent);
|
Result<bool> set_region(u64 address, usize count, bool used, int prot, int flags, off_t offset, u64 shmid,
|
||||||
|
bool persistent);
|
||||||
Result<void> create_default_region();
|
Result<void> create_default_region();
|
||||||
Result<void> create_null_region();
|
Result<void> create_null_region();
|
||||||
void try_merge_region_with_neighbors(VMRegion* region);
|
void try_merge_region_with_neighbors(VMRegion* region);
|
||||||
|
@ -16,9 +16,6 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
mmap_params params;
|
mmap_params params;
|
||||||
if (!MemoryManager::copy_from_user_typed((const mmap_params*)args[0], ¶ms)) return err(EFAULT);
|
if (!MemoryManager::copy_from_user_typed((const mmap_params*)args[0], ¶ms)) return err(EFAULT);
|
||||||
|
|
||||||
kdbgln("mmap: address=%p, len=%zu, prot=%d, flags=%d, fd=%d, offset=%lu", params.addr, params.len, params.prot,
|
|
||||||
params.flags, params.fd, params.offset);
|
|
||||||
|
|
||||||
if (params.len == 0) return err(EINVAL);
|
if (params.len == 0) return err(EINVAL);
|
||||||
|
|
||||||
if (params.flags < 0) return err(EINVAL);
|
if (params.flags < 0) return err(EINVAL);
|
||||||
@ -58,13 +55,14 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
u64 address;
|
u64 address;
|
||||||
if (!params.addr)
|
if (!params.addr)
|
||||||
address = TRY(current->address_space->alloc_region(get_blocks_from_size(params.len, ARCH_PAGE_SIZE),
|
address = TRY(current->address_space->alloc_region(get_blocks_from_size(params.len, ARCH_PAGE_SIZE),
|
||||||
params.prot, params.flags, shmid));
|
params.prot, params.flags, params.offset, shmid));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: We should be more flexible if MAP_FIXED was not specified.
|
// FIXME: We should be more flexible if MAP_FIXED was not specified.
|
||||||
address = align_down<ARCH_PAGE_SIZE>((u64)params.addr);
|
address = align_down<ARCH_PAGE_SIZE>((u64)params.addr);
|
||||||
if (!TRY(current->address_space->test_and_alloc_region(
|
if (!TRY(current->address_space->test_and_alloc_region(address,
|
||||||
address, get_blocks_from_size(params.len, ARCH_PAGE_SIZE), params.prot, params.flags, shmid)))
|
get_blocks_from_size(params.len, ARCH_PAGE_SIZE),
|
||||||
|
params.prot, params.flags, params.offset, shmid)))
|
||||||
return err(ENOMEM);
|
return err(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,3 +108,18 @@ Result<u64> sys_munmap(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<u64> sys_msync(Registers*, SyscallArgs args)
|
||||||
|
{
|
||||||
|
u64 address = (u64)args[0];
|
||||||
|
usize size = (usize)args[1];
|
||||||
|
|
||||||
|
if (!size) return 0;
|
||||||
|
if (!is_aligned<ARCH_PAGE_SIZE>(address)) return err(EINVAL);
|
||||||
|
|
||||||
|
Thread* current = Scheduler::current();
|
||||||
|
|
||||||
|
TRY(current->address_space->sync_regions(address, get_blocks_from_size(size, ARCH_PAGE_SIZE)));
|
||||||
|
|
||||||
|
return { 0 };
|
||||||
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
||||||
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
||||||
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
||||||
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept) _e(poll)
|
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept) _e(poll) _e(msync)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user