mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-28 16:17:51 +01:00
VMA unmap
This commit is contained in:
15
.idea/git_toolbox_prj.xml
generated
Normal file
15
.idea/git_toolbox_prj.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxProjectSettings">
|
||||
<option name="commitMessageIssueKeyValidationOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
<option name="commitMessageValidationEnabledOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@@ -215,14 +215,30 @@ char *syscall_sbrk(int brk) {
|
||||
if (!vma) return reinterpret_cast<char *>(-1);
|
||||
|
||||
if (!vma->brk_start) {
|
||||
vma->brk_start = (char *) vma->mmap_mem(nullptr, VMA::kBrkSize /* 16MB */, 0, PAGE_RW | PAGE_USER);
|
||||
vma->brk_start = (char *) vma->mmap_mem((void *) 0x100000000ULL, VMA::kBrkSize, 0, PAGE_RW | PAGE_USER);
|
||||
if (!vma->brk_start) return reinterpret_cast<char *>(-1); // FIXME:
|
||||
vma->brk_end_real = *vma->brk_start + VMA::kBrkSize;
|
||||
vma->brk_end_fake = vma->brk_start;
|
||||
}
|
||||
|
||||
if (*vma->brk_end_fake + brk >= *vma->brk_start + VMA::kBrkSize) {
|
||||
return ret;
|
||||
if (*vma->brk_end_fake + brk > *vma->brk_end_real) {
|
||||
size_t new_len = PAGE_ROUND_UP((*vma->brk_end_fake + brk - *vma->brk_end_real));
|
||||
void *new_end = vma->mmap_mem(*vma->brk_end_real, new_len, 0, PAGE_RW | PAGE_USER);
|
||||
if (new_end != *vma->brk_end_real) {
|
||||
writestr_no_yield("\nSBRK fail!\n");
|
||||
if (!vma->munmap(new_end, PAGE_ROUND_UP(*vma->brk_end_fake + brk - *vma->brk_end_real)))
|
||||
writestr_no_yield("\nunmap fail after SBRK fail!\n");
|
||||
return reinterpret_cast<char *>(-1);
|
||||
}
|
||||
vma->brk_end_real = (char *) new_end + new_len;
|
||||
} else if (*vma->brk_end_real - (*vma->brk_end_fake + brk) > 3 * PAGE_SIZE) {
|
||||
uintptr_t new_end = PAGE_ROUND_UP((uintptr_t) (*vma->brk_end_fake + brk));
|
||||
uintptr_t length_diff = (uintptr_t) *vma->brk_end_real - new_end;
|
||||
|
||||
if (vma->munmap((void *) new_end, length_diff) == -1)
|
||||
writestr_no_yield("\nunmap fail in sbrk!\n");
|
||||
else
|
||||
*vma->brk_end_real = (char *) new_end;
|
||||
}
|
||||
|
||||
ret = *vma->brk_end_fake;
|
||||
|
||||
@@ -194,9 +194,10 @@ void Task::user_setup() {
|
||||
_ownAddressSpace = UniquePtr(new AddressSpace());
|
||||
_vma = UniquePtr<VMA>(new VMA(_ownAddressSpace.get()));
|
||||
|
||||
static_assert(sizeof(task_pointer) <= PAGE_SIZE);
|
||||
task_pointer *taskptr = static_cast<task_pointer *>(
|
||||
_vma->mmap_mem(reinterpret_cast<void *>(TASK_POINTER),
|
||||
sizeof(task_pointer), 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
|
||||
PAGE_SIZE, 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
|
||||
assert((uintptr_t) taskptr == TASK_POINTER);
|
||||
|
||||
task_pointer *taskptr_real = reinterpret_cast<task_pointer *>(HHDM_P2V(_ownAddressSpace->virt2real(taskptr)));
|
||||
@@ -224,9 +225,10 @@ void Task::user_reset() {
|
||||
|
||||
_vma = UniquePtr<VMA>(new VMA(_ownAddressSpace.get()));
|
||||
|
||||
static_assert(sizeof(task_pointer) <= PAGE_SIZE);
|
||||
task_pointer *taskptr = static_cast<task_pointer *>(
|
||||
_vma->mmap_mem(reinterpret_cast<void *>(TASK_POINTER),
|
||||
sizeof(task_pointer), 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
|
||||
PAGE_SIZE, 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
|
||||
assert((uintptr_t) taskptr == TASK_POINTER);
|
||||
|
||||
task_pointer *taskptr_real = reinterpret_cast<task_pointer *>(HHDM_P2V(_ownAddressSpace->virt2real(taskptr)));
|
||||
|
||||
@@ -81,13 +81,7 @@ void *VMA::mmap_phys(void *v_addr, void *real_addr, size_t length, int flags) {
|
||||
}
|
||||
|
||||
void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
|
||||
size_t origlen = length;
|
||||
if ((length & (PAGE_SIZE - 1)) != 0) {
|
||||
length += PAGE_SIZE - 1;
|
||||
length &= ~(PAGE_SIZE - 1);
|
||||
}
|
||||
assert((length & (PAGE_SIZE - 1)) == 0);
|
||||
assert(length >= origlen);
|
||||
|
||||
uint64_t page_len = length / PAGE_SIZE;
|
||||
|
||||
@@ -107,6 +101,73 @@ void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
|
||||
return reinterpret_cast<void *>(found->begin);
|
||||
}
|
||||
int VMA::munmap(void *addr, size_t length) {
|
||||
assert((length & (PAGE_SIZE - 1)) == 0);
|
||||
assert((((uintptr_t) addr) & (PAGE_SIZE - 1)) == 0);
|
||||
|
||||
uint64_t page_len = length / PAGE_SIZE;
|
||||
|
||||
uintptr_t end = (uintptr_t) addr + length;
|
||||
uintptr_t cur = (uintptr_t) addr;
|
||||
|
||||
while (cur < end) {
|
||||
LockGuard l(regions_lock);
|
||||
auto found = regions.upper_bound(cur);
|
||||
--found;
|
||||
|
||||
if (found->second.type == EntryType::FREE) {
|
||||
cur += found->second.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
ListEntry old = found->second;
|
||||
regions.erase(found);
|
||||
|
||||
if (old.begin < cur)
|
||||
regions.emplace(std::make_pair<uintptr_t, ListEntry>((uintptr_t) old.begin, {old.begin, cur - old.begin, old.type, old.flags}));
|
||||
|
||||
old.length = old.length - (cur - old.begin);
|
||||
old.begin = cur;
|
||||
|
||||
if (old.begin + old.length > end)
|
||||
regions.emplace(std::make_pair<uintptr_t, ListEntry>((uintptr_t) end, {end, (old.begin + old.length) - end, old.type, old.flags}));
|
||||
|
||||
old.length = std::min(old.length, length);
|
||||
|
||||
size_t new_free_len = old.length;
|
||||
|
||||
|
||||
uint64_t cur_page_len = new_free_len / PAGE_SIZE;
|
||||
|
||||
for (int i = 0; i < cur_page_len; i++) {
|
||||
free4k((void *) HHDM_P2V(space->virt2real(reinterpret_cast<void *>(old.begin + i * PAGE_SIZE))));
|
||||
{
|
||||
LockGuard l(space_lock);
|
||||
space->unmap(reinterpret_cast<void *>(old.begin + i * PAGE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
// Merge free pages together
|
||||
auto ub = regions.upper_bound(cur);
|
||||
while (ub != regions.end() && ub->second.begin == (cur + new_free_len) && ub->second.type == EntryType::FREE) {
|
||||
auto ubold = ub;
|
||||
++ub;
|
||||
new_free_len += ubold->second.length;
|
||||
regions.erase(ubold);
|
||||
}
|
||||
ub = regions.upper_bound(cur);
|
||||
--ub;
|
||||
while (ub != regions.end() && (ub->second.begin + ub->second.length) == cur && ub->second.type == EntryType::FREE) {
|
||||
auto ubold = ub;
|
||||
--ub;
|
||||
cur = ubold->second.begin;
|
||||
new_free_len += ubold->second.length;
|
||||
regions.erase(ubold);
|
||||
}
|
||||
|
||||
regions.emplace(std::make_pair<uintptr_t, ListEntry>((uintptr_t) cur, {cur, new_free_len, EntryType::FREE, old.flags}));
|
||||
|
||||
cur = cur + new_free_len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
VMA::~VMA() {
|
||||
|
||||
@@ -16,11 +16,11 @@ class AddressSpace;
|
||||
|
||||
class VMA {
|
||||
public:
|
||||
VMA(AddressSpace *space);
|
||||
VMA(AddressSpace *space);
|
||||
~VMA();
|
||||
|
||||
VMA(const VMA &) = delete;
|
||||
VMA(VMA &&) = delete;
|
||||
VMA(const VMA &) = delete;
|
||||
VMA(VMA &&) = delete;
|
||||
VMA &operator=(const VMA &) = delete;
|
||||
VMA &operator=(VMA &&) = delete;
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
void *mmap_mem(void *v_addr, size_t length, int prot, int flags);
|
||||
int munmap(void *addr, size_t length);
|
||||
|
||||
static constexpr size_t kBrkSize = 16ULL * 1024ULL * 1024ULL;
|
||||
static constexpr size_t kBrkSize = 4096ULL * 20ULL;
|
||||
std::optional<char *> brk_start;
|
||||
std::optional<char *> brk_end_fake;
|
||||
std::optional<char *> brk_end_real;
|
||||
|
||||
@@ -108,7 +108,7 @@ bool ElfParser::copy_to(Task *task) {
|
||||
}
|
||||
|
||||
auto rounded_vaddr = hdr.p_vaddr & 0x000FFFFFFFFFF000ULL;
|
||||
auto real_memsz = hdr.p_memsz + (hdr.p_vaddr - rounded_vaddr);
|
||||
auto real_memsz = PAGE_ROUND_UP(hdr.p_memsz + (hdr.p_vaddr - rounded_vaddr));
|
||||
|
||||
uintptr_t real_ptr = reinterpret_cast<uintptr_t>(task->_vma->mmap_mem(reinterpret_cast<void *>(rounded_vaddr), real_memsz, 0, flags | PAGE_USER));
|
||||
if (real_ptr != rounded_vaddr) return false;
|
||||
|
||||
@@ -32,14 +32,6 @@ int main() {
|
||||
close(test123);
|
||||
printf("\n %s \n", buf);
|
||||
}
|
||||
while (1) {
|
||||
if (fork() == 0)
|
||||
execve("hello2", 0, 0);
|
||||
else
|
||||
wait(NULL);
|
||||
print_mem();
|
||||
sleep(500);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
printf("\n> ");
|
||||
|
||||
Reference in New Issue
Block a user