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:
parent
b2d6c81074
commit
c5f2c1f0b7
4 changed files with 56 additions and 8 deletions
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue