1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add option to map zeroed pages

- add also an option to remap pages without IPIs
- be sure that an IPIs is not required
This commit is contained in:
Stefan Lankes 2016-10-03 23:15:09 +02:00
parent b2d6c81074
commit c5f2c1f0b7
4 changed files with 56 additions and 8 deletions

View file

@ -165,9 +165,23 @@ int page_init(void);
* @param phyaddr Physical address to map from
* @param npages The region's size in number of pages
* @param bits Further page flags
* @param do_ipi if set, inform via IPI all other cores
* @return
*/
int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits);
int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits, uint8_t do_ipi);
/** @brief Map a continuous region of pages
*
* @param viraddr Desired virtual address
* @param phyaddr Physical address to map from
* @param npages The region's size in number of pages
* @param bits Further page flags
* @return
*/
static inline int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
{
return __page_map(viraddr, phyaddr, npages, bits, 1);
}
/** @brief Unmap a continuous region of pages
*

View file

@ -112,7 +112,7 @@ int page_set_flags(size_t viraddr, uint32_t npages, int flags)
return -EINVAL;
}
int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
int __page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits, uint8_t do_ipi)
{
int lvl, ret = -ENOMEM;
long vpn = viraddr >> PAGE_BITS;
@ -169,7 +169,7 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
}
}
if (send_ipi)
if (do_ipi && send_ipi)
ipi_tlb_flush();
ret = 0;
@ -246,8 +246,7 @@ void page_fault_handler(struct state *s)
// on demand userspace heap mapping
viraddr &= PAGE_MASK;
// TODO: a function to get zeroed pages is missing
size_t phyaddr = get_page();
size_t phyaddr = get_zeroed_page();
if (BUILTIN_EXPECT(!phyaddr, 0)) {
kprintf("out of memory: task = %u\n", task->id);
goto default_handler;
@ -265,9 +264,6 @@ void page_fault_handler(struct state *s)
goto default_handler;
}
// reset page
memset(viraddr, 0x00, PAGE_SIZE);
spinlock_irqsave_unlock(&page_lock);
return;

View file

@ -48,6 +48,9 @@ size_t get_pages(size_t npages);
*/
static inline size_t get_page(void) { return get_pages(1); }
/** @brief Get a single zeroed page */
size_t get_zeroed_page(void);
/** @brief release physical page frames */
int put_pages(size_t phyaddr, size_t npages);

View file

@ -30,6 +30,7 @@
#include <hermit/stdio.h>
#include <hermit/string.h>
#include <hermit/spinlock.h>
#include <hermit/memory.h>
#include <asm/atomic.h>
#include <asm/page.h>
@ -104,6 +105,40 @@ out:
return ret;
}
DEFINE_PER_CORE(size_t, ztmp_addr, 0);
size_t get_zeroed_page(void)
{
size_t phyaddr = get_page();
size_t viraddr;
uint8_t flags;
if (BUILTIN_EXPECT(!phyaddr, 0))
return 0;
flags = irq_nested_disable();
viraddr = per_core(ztmp_addr);
if (BUILTIN_EXPECT(!viraddr, 0))
{
viraddr = vma_alloc(PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
if (BUILTIN_EXPECT(!viraddr, 0))
goto novaddr;
//kprintf("Core %d uses 0x%zx as temporary address\n", CORE_ID, viraddr);
set_per_core(ztmp_addr, viraddr);
}
__page_map(viraddr, phyaddr, 1, PG_GLOBAL|PG_RW|PG_PRESENT, 0);
memset((void*) viraddr, 0x00, PAGE_SIZE);
novaddr:
irq_nested_enable(flags);
return phyaddr;
}
/* TODO: reunion of elements is still missing */
int put_pages(size_t phyaddr, size_t npages)
{