process: track ownership of pages in a more flexible way
This commit is contained in:
parent
f5ccce54a4
commit
aa54761c77
2 changed files with 29 additions and 10 deletions
|
|
@ -58,6 +58,7 @@ void create_process(struct process *process_out) {
|
||||||
process_out->p3_virtual_base[i] = 0;
|
process_out->p3_virtual_base[i] = 0;
|
||||||
process_out->p2_virtual_bases[i] = 0;
|
process_out->p2_virtual_bases[i] = 0;
|
||||||
process_out->p1_virtual_bases[i] = 0;
|
process_out->p1_virtual_bases[i] = 0;
|
||||||
|
process_out->owned_pages_bitmaps[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
process_out->n_threads = 0;
|
process_out->n_threads = 0;
|
||||||
|
|
@ -67,7 +68,7 @@ void create_process(struct process *process_out) {
|
||||||
|
|
||||||
void map_page_for_process(
|
void map_page_for_process(
|
||||||
struct process *process, uint64_t physical_base,
|
struct process *process, uint64_t physical_base,
|
||||||
void *virtual_base, int writable, int executable) {
|
void *virtual_base, int writable, int executable, int owned) {
|
||||||
|
|
||||||
assert(physical_base % 4096 == 0)
|
assert(physical_base % 4096 == 0)
|
||||||
|
|
||||||
|
|
@ -87,9 +88,11 @@ void map_page_for_process(
|
||||||
process->p3_virtual_base[p3i] = p2_pma | 0x7;
|
process->p3_virtual_base[p3i] = p2_pma | 0x7;
|
||||||
process->p2_virtual_bases[p3i] = p2_vma;
|
process->p2_virtual_bases[p3i] = p2_vma;
|
||||||
process->p1_virtual_bases[p3i] = heap_alloc(4096);
|
process->p1_virtual_bases[p3i] = heap_alloc(4096);
|
||||||
|
process->owned_pages_bitmaps[p3i] = heap_alloc(4096);
|
||||||
for (int i = 0; i < 512; ++i) {
|
for (int i = 0; i < 512; ++i) {
|
||||||
p2_vma[i] = 0;
|
p2_vma[i] = 0;
|
||||||
process->p1_virtual_bases[p3i][i] = 0;
|
process->p1_virtual_bases[p3i][i] = 0;
|
||||||
|
process->owned_pages_bitmaps[p3i][i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,8 +102,11 @@ void map_page_for_process(
|
||||||
map_in_kernel_page_table(p1_pma, p1_vma, 1, 0);
|
map_in_kernel_page_table(p1_pma, p1_vma, 1, 0);
|
||||||
process->p2_virtual_bases[p3i][p2i] = p1_pma | 0x7;
|
process->p2_virtual_bases[p3i][p2i] = p1_pma | 0x7;
|
||||||
process->p1_virtual_bases[p3i][p2i] = p1_vma;
|
process->p1_virtual_bases[p3i][p2i] = p1_vma;
|
||||||
|
process->owned_pages_bitmaps[p3i][p2i] = heap_alloc(64);
|
||||||
for (int i = 0; i < 512; ++i)
|
for (int i = 0; i < 512; ++i)
|
||||||
p1_vma[i] = 0;
|
p1_vma[i] = 0;
|
||||||
|
for (int i = 0; i < 64; ++i)
|
||||||
|
process->owned_pages_bitmaps[p3i][p2i][i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(process->p1_virtual_bases[p3i][p2i][p1i] == 0)
|
assert(process->p1_virtual_bases[p3i][p2i][p1i] == 0)
|
||||||
|
|
@ -109,6 +115,9 @@ void map_page_for_process(
|
||||||
physical_base | 0x5 | (writable ? 0x2 : 0x0) |
|
physical_base | 0x5 | (writable ? 0x2 : 0x0) |
|
||||||
(executable ? 0 : 0x8000000000000000);
|
(executable ? 0 : 0x8000000000000000);
|
||||||
|
|
||||||
|
if (owned)
|
||||||
|
process->owned_pages_bitmaps[p3i][p2i][p1i / 8] |= 1 << (p1i % 8);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmap_page_for_process(
|
void unmap_page_for_process(
|
||||||
|
|
@ -128,6 +137,12 @@ void unmap_page_for_process(
|
||||||
process->p1_virtual_bases[p3i][p2i] &&
|
process->p1_virtual_bases[p3i][p2i] &&
|
||||||
process->p1_virtual_bases[p3i][p2i][p1i])
|
process->p1_virtual_bases[p3i][p2i][p1i])
|
||||||
|
|
||||||
|
if (process->owned_pages_bitmaps[p3i][p2i][p1i / 8] & (1 << (p1i % 8))) {
|
||||||
|
process->owned_pages_bitmaps[p3i][p2i][p1i / 8] &= ~(1 << (p1i % 8));
|
||||||
|
uint64_t pma = process->p1_virtual_bases[p3i][p2i][p1i] & 0x7ffffffffffff000;
|
||||||
|
mark_physical_memory_free(pma, 4096);
|
||||||
|
}
|
||||||
|
|
||||||
process->p1_virtual_bases[p3i][p2i][p1i] = 0;
|
process->p1_virtual_bases[p3i][p2i][p1i] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -286,7 +301,7 @@ int load_elf(
|
||||||
|
|
||||||
uint64_t pma = take_free_physical_page();
|
uint64_t pma = take_free_physical_page();
|
||||||
map_page_for_process(
|
map_page_for_process(
|
||||||
process, pma, virtual_start + i, writable, executable);
|
process, pma, virtual_start + i, writable, executable, 1);
|
||||||
|
|
||||||
void *kvma = find_free_kernel_region(4096);
|
void *kvma = find_free_kernel_region(4096);
|
||||||
map_in_kernel_page_table(pma, kvma, 1, 0);
|
map_in_kernel_page_table(pma, kvma, 1, 0);
|
||||||
|
|
@ -377,15 +392,15 @@ void destroy_process(struct process *process) {
|
||||||
for (int p1i = 0; p1i < 512; ++p1i) {
|
for (int p1i = 0; p1i < 512; ++p1i) {
|
||||||
uint64_t pma =
|
uint64_t pma =
|
||||||
process->p1_virtual_bases[p3i][p2i][p1i] & 0x7ffffffffffff000;
|
process->p1_virtual_bases[p3i][p2i][p1i] & 0x7ffffffffffff000;
|
||||||
if (pma >= fb_physical_base &&
|
if (process->owned_pages_bitmaps[p3i][p2i][p1i / 8] & (1 << (p1i % 8)))
|
||||||
pma < fb_physical_base + fb_pitch * fb_height)
|
mark_physical_memory_free(pma, 4096);
|
||||||
continue;
|
|
||||||
mark_physical_memory_free(pma, 4096);
|
|
||||||
}
|
}
|
||||||
unmap_and_free_kernel_page(process->p1_virtual_bases[p3i][p2i]);
|
unmap_and_free_kernel_page(process->p1_virtual_bases[p3i][p2i]);
|
||||||
|
heap_dealloc(process->owned_pages_bitmaps[p3i][p2i], 64);
|
||||||
}
|
}
|
||||||
unmap_and_free_kernel_page(process->p2_virtual_bases[p3i]);
|
unmap_and_free_kernel_page(process->p2_virtual_bases[p3i]);
|
||||||
heap_dealloc(process->p1_virtual_bases[p3i], 4096);
|
heap_dealloc(process->p1_virtual_bases[p3i], 4096);
|
||||||
|
heap_dealloc(process->owned_pages_bitmaps[p3i], 4096);
|
||||||
}
|
}
|
||||||
unmap_and_free_kernel_page(process->p3_virtual_base);
|
unmap_and_free_kernel_page(process->p3_virtual_base);
|
||||||
unmap_and_free_kernel_page(process->p4_virtual_base);
|
unmap_and_free_kernel_page(process->p4_virtual_base);
|
||||||
|
|
@ -426,7 +441,7 @@ void create_thread(struct process *process, struct thread *thread_out) {
|
||||||
|
|
||||||
uint64_t pma = take_free_physical_page();
|
uint64_t pma = take_free_physical_page();
|
||||||
map_page_for_process(
|
map_page_for_process(
|
||||||
process, pma, stack_bottom_vma + i * 4096, 1, 0);
|
process, pma, stack_bottom_vma + i * 4096, 1, 0, 1);
|
||||||
|
|
||||||
void *kvma = find_free_kernel_region(4096);
|
void *kvma = find_free_kernel_region(4096);
|
||||||
map_in_kernel_page_table(pma, kvma, 1, 0);
|
map_in_kernel_page_table(pma, kvma, 1, 0);
|
||||||
|
|
@ -478,7 +493,7 @@ void syscall_map_framebuffer(struct framebuffer_info *info_out) {
|
||||||
map_page_for_process(
|
map_page_for_process(
|
||||||
running_thread->process,
|
running_thread->process,
|
||||||
fb_physical_base + i * 4096,
|
fb_physical_base + i * 4096,
|
||||||
base + i * 4096, 1, 0);
|
base + i * 4096, 1, 0, 0);
|
||||||
|
|
||||||
info_out->fb_base = base;
|
info_out->fb_base = base;
|
||||||
info_out->fb_pitch = fb_pitch;
|
info_out->fb_pitch = fb_pitch;
|
||||||
|
|
@ -605,7 +620,7 @@ void *syscall_map_pages(uint64_t count) {
|
||||||
map_page_for_process(
|
map_page_for_process(
|
||||||
running_thread->process,
|
running_thread->process,
|
||||||
pma, vma + i * 4096,
|
pma, vma + i * 4096,
|
||||||
1, 0);
|
1, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vma;
|
return vma;
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@ struct process {
|
||||||
uint64_t *p2_virtual_bases[512];
|
uint64_t *p2_virtual_bases[512];
|
||||||
uint64_t **p1_virtual_bases[512];
|
uint64_t **p1_virtual_bases[512];
|
||||||
|
|
||||||
|
//also just bottom p3. bit set indicates we should free
|
||||||
|
//the physical page when we clean up this process.
|
||||||
|
uint8_t **owned_pages_bitmaps[512];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//returns 0 if that handle is not used.
|
//returns 0 if that handle is not used.
|
||||||
|
|
@ -71,7 +75,7 @@ void create_thread(struct process *process, struct thread *thread_out);
|
||||||
//virtual base must be in bottom p3 and not zero.
|
//virtual base must be in bottom p3 and not zero.
|
||||||
void map_page_for_process(
|
void map_page_for_process(
|
||||||
struct process *process, uint64_t physical_base,
|
struct process *process, uint64_t physical_base,
|
||||||
void *virtual_base, int writable, int executable);
|
void *virtual_base, int writable, int executable, int owned);
|
||||||
|
|
||||||
//virtual base must be page-aligned, in bottom p3, and not zero.
|
//virtual base must be page-aligned, in bottom p3, and not zero.
|
||||||
void unmap_page_for_process(
|
void unmap_page_for_process(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue