rewrite sys_mmap() as sys_new_mmap()
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
static char *last_page;
|
static char *last_page;
|
||||||
extern char _head[], _end[];
|
extern char _head[], _end[];
|
||||||
@@ -638,109 +639,57 @@ int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt)
|
|||||||
return __clear_pt_page(pt, virt, 1);
|
return __clear_pt_page(pt, virt, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clear_range_l1(struct page_table *pt, uint64_t base, uint64_t start, uint64_t end)
|
typedef int walk_pte_fn_t(void *args, pte_t *ptep, uint64_t base,
|
||||||
{
|
uint64_t start, uint64_t end);
|
||||||
int six;
|
|
||||||
int eix;
|
static int walk_pte_l1(struct page_table *pt, uint64_t base, uint64_t start,
|
||||||
int ret;
|
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||||
int i;
|
|
||||||
|
|
||||||
six = (start <= base)? 0: (start - base) >> PTL1_SHIFT;
|
|
||||||
eix = ((base + PTL2_SIZE) <= end)? PT_ENTRIES
|
|
||||||
: ((end - base) + (PTL1_SIZE - 1)) >> PTL1_SHIFT;
|
|
||||||
|
|
||||||
ret = -ENOENT;
|
|
||||||
for (i = six; i < eix; ++i) {
|
|
||||||
if (!(pt->entry[i] & PFL1_PRESENT)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt->entry[i] = 0;
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int clear_range_l2(struct page_table *pt, uint64_t base, uint64_t start, uint64_t end)
|
|
||||||
{
|
{
|
||||||
int six;
|
int six;
|
||||||
int eix;
|
int eix;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
int error;
|
||||||
uint64_t off;
|
uint64_t off;
|
||||||
struct page_table *q;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
six = (start <= base)? 0: (start - base) >> PTL2_SHIFT;
|
six = (start <= base)? 0: ((start - base) >> PTL1_SHIFT);
|
||||||
eix = ((base + PTL3_SIZE) <= end)? PT_ENTRIES
|
eix = ((end == 0) || ((base + PTL2_SIZE) <= end))? PT_ENTRIES
|
||||||
: ((end - base) + (PTL2_SIZE - 1)) >> PTL2_SHIFT;
|
: (((end - base) + (PTL1_SIZE - 1)) >> PTL1_SHIFT);
|
||||||
|
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
for (i = six; i < eix; ++i) {
|
for (i = six; i < eix; ++i) {
|
||||||
if (!(pt->entry[i] & PFL2_PRESENT)) {
|
off = i * PTL1_SIZE;
|
||||||
continue;
|
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||||
|
if (!error) {
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
else if (error != -ENOENT) {
|
||||||
|
ret = error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int walk_pte_l2(struct page_table *pt, uint64_t base, uint64_t start,
|
||||||
|
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||||
|
{
|
||||||
|
int six;
|
||||||
|
int eix;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
int error;
|
||||||
|
uint64_t off;
|
||||||
|
|
||||||
|
six = (start <= base)? 0: ((start - base) >> PTL2_SHIFT);
|
||||||
|
eix = ((end == 0) || ((base + PTL3_SIZE) <= end))? PT_ENTRIES
|
||||||
|
: (((end - base) + (PTL2_SIZE - 1)) >> PTL2_SHIFT);
|
||||||
|
|
||||||
|
ret = -ENOENT;
|
||||||
|
for (i = six; i < eix; ++i) {
|
||||||
off = i * PTL2_SIZE;
|
off = i * PTL2_SIZE;
|
||||||
|
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||||
if (pt->entry[i] & PFL2_SIZE) {
|
|
||||||
if (((base + off) < start) || (end < (base + off + PTL2_SIZE))) {
|
|
||||||
kprintf("clear_range_l2(%p,%lx,%lx,%lx):"
|
|
||||||
"not a 2MiB page boundary\n",
|
|
||||||
pt, base, start, end);
|
|
||||||
ret = -ERANGE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt->entry[i] = 0;
|
|
||||||
ret = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
q = phys_to_virt(pt->entry[i] & PT_PHYSMASK);
|
|
||||||
|
|
||||||
if ((start <= (base + off)) && ((base + off + PTL2_SIZE) <= end)) {
|
|
||||||
pt->entry[i] = 0;
|
|
||||||
ret = 0;
|
|
||||||
arch_free_page(q);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error = clear_range_l1(q, base+off, start, end);
|
|
||||||
if (!error) {
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
else if (error != -ENOENT) {
|
|
||||||
ret = error;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int clear_range_l3(struct page_table *pt, uint64_t base, uint64_t start, uint64_t end)
|
|
||||||
{
|
|
||||||
int six;
|
|
||||||
int eix;
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
int error;
|
|
||||||
struct page_table *q;
|
|
||||||
|
|
||||||
six = (start <= base)? 0: (start - base) >> PTL3_SHIFT;
|
|
||||||
eix = ((base + PTL4_SIZE) <= end)? PT_ENTRIES
|
|
||||||
: ((end - base) + (PTL3_SIZE - 1)) >> PTL3_SHIFT;
|
|
||||||
|
|
||||||
ret = -ENOENT;
|
|
||||||
for (i = six; i < eix; ++i) {
|
|
||||||
if (!(pt->entry[i] & PFL3_PRESENT)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
q = phys_to_virt(pt->entry[i] & PT_PHYSMASK);
|
|
||||||
error = clear_range_l2(q, base+(i*PTL3_SIZE), start, end);
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
@@ -753,29 +702,24 @@ static int clear_range_l3(struct page_table *pt, uint64_t base, uint64_t start,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clear_range_l4(struct page_table *pt, uint64_t base, uint64_t start, uint64_t end)
|
static int walk_pte_l3(struct page_table *pt, uint64_t base, uint64_t start,
|
||||||
|
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||||
{
|
{
|
||||||
int six;
|
int six;
|
||||||
int eix;
|
int eix;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
int error;
|
int error;
|
||||||
struct page_table *q;
|
uint64_t off;
|
||||||
|
|
||||||
six = (start <= base)? 0: (start - base) >> PTL4_SHIFT;
|
six = (start <= base)? 0: ((start - base) >> PTL3_SHIFT);
|
||||||
eix = ((end - base) + (PTL4_SIZE - 1)) >> PTL4_SHIFT;
|
eix = ((end == 0) || ((base + PTL4_SIZE) <= end))? PT_ENTRIES
|
||||||
if ((eix <= 0) || (PT_ENTRIES < eix)) {
|
: (((end - base) + (PTL3_SIZE - 1)) >> PTL3_SHIFT);
|
||||||
eix = PT_ENTRIES;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
for (i = six; i < eix; ++i) {
|
for (i = six; i < eix; ++i) {
|
||||||
if (!(pt->entry[i] & PFL4_PRESENT)) {
|
off = i * PTL3_SIZE;
|
||||||
continue;
|
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||||
}
|
|
||||||
|
|
||||||
q = phys_to_virt(pt->entry[i] & PT_PHYSMASK);
|
|
||||||
error = clear_range_l3(q, base+(i*PTL4_SIZE), start, end);
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
@@ -788,6 +732,127 @@ static int clear_range_l4(struct page_table *pt, uint64_t base, uint64_t start,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int walk_pte_l4(struct page_table *pt, uint64_t base, uint64_t start,
|
||||||
|
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||||
|
{
|
||||||
|
int six;
|
||||||
|
int eix;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
int error;
|
||||||
|
uint64_t off;
|
||||||
|
|
||||||
|
six = (start <= base)? 0: ((start - base) >> PTL4_SHIFT);
|
||||||
|
eix = (end == 0)? PT_ENTRIES
|
||||||
|
:(((end - base) + (PTL4_SIZE - 1)) >> PTL4_SHIFT);
|
||||||
|
|
||||||
|
ret = -ENOENT;
|
||||||
|
for (i = six; i < eix; ++i) {
|
||||||
|
off = i * PTL4_SIZE;
|
||||||
|
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||||
|
if (!error) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else if (error != -ENOENT) {
|
||||||
|
ret = error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct clear_range_args {
|
||||||
|
int free_physical;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base, uint64_t start, uint64_t end)
|
||||||
|
{
|
||||||
|
struct clear_range_args *args = args0;
|
||||||
|
uint64_t phys;
|
||||||
|
|
||||||
|
if (!(*ptep & PFL1_PRESENT)) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
phys = *ptep & PT_PHYSMASK;
|
||||||
|
*ptep = 0;
|
||||||
|
|
||||||
|
if (args->free_physical) {
|
||||||
|
ihk_mc_free_pages(phys_to_virt(phys), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base, uint64_t start, uint64_t end)
|
||||||
|
{
|
||||||
|
struct clear_range_args *args = args0;
|
||||||
|
uint64_t phys;
|
||||||
|
struct page_table *pt;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (!(*ptep & PFL2_PRESENT)) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptep & PFL2_SIZE) {
|
||||||
|
if ((base < start) || (end < (base + PTL2_SIZE))) {
|
||||||
|
kprintf("clear_range_l2(%p,%p,%lx,%lx,%lx):"
|
||||||
|
"not a 2MiB page boundary\n",
|
||||||
|
args0, ptep, base, start, end);
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
phys = *ptep & PT_PHYSMASK;
|
||||||
|
*ptep = 0;
|
||||||
|
|
||||||
|
if (args->free_physical) {
|
||||||
|
ihk_mc_free_pages(phys_to_virt(phys),
|
||||||
|
LARGE_PAGE_SIZE/PAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||||
|
error = walk_pte_l1(pt, base, start, end, &clear_range_l1, args0);
|
||||||
|
if (error && (error != -ENOENT)) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((start <= base) && ((base + PTL2_SIZE) <= end)) {
|
||||||
|
*ptep = 0;
|
||||||
|
arch_free_page(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clear_range_l3(void *args0, pte_t *ptep, uint64_t base, uint64_t start, uint64_t end)
|
||||||
|
{
|
||||||
|
struct page_table *pt;
|
||||||
|
|
||||||
|
if (!(*ptep & PFL3_PRESENT)) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||||
|
return walk_pte_l2(pt, base, start, end, &clear_range_l2, args0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clear_range_l4(void *args0, pte_t *ptep, uint64_t base, uint64_t start, uint64_t end)
|
||||||
|
{
|
||||||
|
struct page_table *pt;
|
||||||
|
|
||||||
|
if (!(*ptep & PFL4_PRESENT)) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||||
|
return walk_pte_l3(pt, base, start, end, &clear_range_l3, args0);
|
||||||
|
}
|
||||||
|
|
||||||
static int lookup_pte(struct page_table *pt, void *virt, pte_t **ptep, void **pgbasep, uint64_t *pgsizep)
|
static int lookup_pte(struct page_table *pt, void *virt, pte_t **ptep, void **pgbasep, uint64_t *pgsizep)
|
||||||
{
|
{
|
||||||
int l4idx, l3idx, l2idx, l1idx;
|
int l4idx, l3idx, l2idx, l1idx;
|
||||||
@@ -819,53 +884,91 @@ static int lookup_pte(struct page_table *pt, void *virt, pte_t **ptep, void **pg
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_middle_of_the_page(struct page_table *pt, void *virt)
|
#ifdef USE_LARGE_PAGES
|
||||||
|
static int split_large_page(struct page_table *pt, intptr_t virt)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
pte_t *pte;
|
pte_t *ptep;
|
||||||
void *pgbase;
|
void *pgbase;
|
||||||
uint64_t pgsize;
|
uint64_t pgsize;
|
||||||
|
struct page_table *q;
|
||||||
|
uint64_t phys;
|
||||||
|
pte_t attr;
|
||||||
|
int i;
|
||||||
|
|
||||||
error = lookup_pte(pt, virt, &pte, &pgbase, &pgsize);
|
error = lookup_pte(pt, (void *)virt, &ptep, &pgbase, &pgsize);
|
||||||
if (error) {
|
if (error || !(*ptep & PF_PRESENT) || (pgsize == PAGE_SIZE)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*pte & PF_PRESENT)) {
|
q = __alloc_new_pt(IHK_MC_AP_NOWAIT);
|
||||||
return 0;
|
if (q == NULL) {
|
||||||
|
kprintf("split_large_page:__alloc_new_pt failed\n");
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pgbase != virt;
|
phys = *ptep & PT_PHYSMASK;
|
||||||
|
attr = *ptep & (PFL2_PRESENT | PFL2_WRITABLE | PFL2_USER | PFL2_PWT | PFL2_PCD);
|
||||||
|
|
||||||
|
for (i = 0; i < PT_ENTRIES; ++i) {
|
||||||
|
q->entry[i] = (phys + (i * PTL1_SIZE)) | attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptep = (virt_to_phys(q) & PT_PHYSMASK) | PFL2_PDIR_ATTR;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* USE_LARGE_PAGES */
|
||||||
|
|
||||||
int ihk_mc_pt_clear_range(page_table_t pt, void *start0, void *end0)
|
static int clear_range(page_table_t pt, void *start0, void *end0, int free_physical)
|
||||||
{
|
{
|
||||||
const uint64_t start = (uint64_t)start0;
|
const uint64_t start = (uint64_t)start0;
|
||||||
const uint64_t end = (uint64_t)end0;
|
const uint64_t end = (uint64_t)end0;
|
||||||
int error;
|
int error;
|
||||||
|
struct clear_range_args args;
|
||||||
|
|
||||||
if ((USER_END <= start) || (USER_END < end) || (end <= start)) {
|
if ((USER_END <= start) || (USER_END < end) || (end <= start)) {
|
||||||
kprintf("ihk_mc_pt_clear_range(%p,%p,%p):invalid start and/or end.\n",
|
kprintf("clear_range(%p,%p,%p,%x):invalid start and/or end.\n",
|
||||||
pt, start0, end0);
|
pt, start0, end0, free_physical);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((start % LARGE_PAGE_SIZE) != 0) && is_middle_of_the_page(pt, start0)) {
|
#ifdef USE_LARGE_PAGES
|
||||||
kprintf("ihk_mc_pt_clear_range(%p,%p,%p):start0 is not a page boundary\n",
|
if (start & (LARGE_PAGE_SIZE - 1)) {
|
||||||
pt, start0, end0);
|
error = split_large_page(pt, start);
|
||||||
return -EINVAL;
|
if (error) {
|
||||||
|
kprintf("clear_range(%p,%p,%p,%x):split_large_page(%lx) failed. %d\n",
|
||||||
|
pt, start0, end0, free_physical, start, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((end % LARGE_PAGE_SIZE) != 0) && is_middle_of_the_page(pt, end0)) {
|
if (end & (LARGE_PAGE_SIZE - 1)) {
|
||||||
kprintf("ihk_mc_pt_clear_range(%p,%p,%p):end0 is not a page boundary\n",
|
error = split_large_page(pt, end);
|
||||||
pt, start0, end0);
|
if (error) {
|
||||||
return -EINVAL;
|
kprintf("clear_range(%p,%p,%p,%x):split_large_page(%lx) failed. %d\n",
|
||||||
|
pt, start0, end0, free_physical, end, error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* USE_LARGE_PAGES */
|
||||||
|
|
||||||
error = clear_range_l4(pt, 0, start, end);
|
args.free_physical = free_physical;
|
||||||
|
error = walk_pte_l4(pt, 0, start, end, &clear_range_l4, &args);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ihk_mc_pt_clear_range(page_table_t pt, void *start0, void *end0)
|
||||||
|
{
|
||||||
|
#define KEEP_PHYSICAL 0
|
||||||
|
return clear_range(pt, start0, end0, KEEP_PHYSICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ihk_mc_pt_free_range(page_table_t pt, void *start0, void *end0)
|
||||||
|
{
|
||||||
|
#define FREE_PHYSICAL 1
|
||||||
|
return clear_range(pt, start0, end0, FREE_PHYSICAL);
|
||||||
|
}
|
||||||
|
|
||||||
void load_page_table(struct page_table *pt)
|
void load_page_table(struct page_table *pt)
|
||||||
{
|
{
|
||||||
unsigned long pt_addr;
|
unsigned long pt_addr;
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ struct program_image_section {
|
|||||||
unsigned long len;
|
unsigned long len;
|
||||||
unsigned long remote_pa;
|
unsigned long remote_pa;
|
||||||
unsigned long filesz, offset;
|
unsigned long filesz, offset;
|
||||||
|
int prot;
|
||||||
|
int padding;
|
||||||
|
#if 0
|
||||||
void *source;
|
void *source;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct program_load_desc {
|
struct program_load_desc {
|
||||||
|
|||||||
@@ -124,12 +124,18 @@ struct program_load_desc *load_elf(FILE *fp)
|
|||||||
desc->sections[j].offset = phdr.p_offset;
|
desc->sections[j].offset = phdr.p_offset;
|
||||||
desc->sections[j].len = phdr.p_memsz;
|
desc->sections[j].len = phdr.p_memsz;
|
||||||
|
|
||||||
__dprintf("%d: (%s) %lx, %lx, %lx, %lx\n",
|
desc->sections[j].prot = PROT_NONE;
|
||||||
j, (phdr.p_type == PT_LOAD ? "PT_LOAD" : "PT_TLS"),
|
desc->sections[j].prot |= (phdr.p_flags & PF_R)? PROT_READ: 0;
|
||||||
desc->sections[j].vaddr,
|
desc->sections[j].prot |= (phdr.p_flags & PF_W)? PROT_WRITE: 0;
|
||||||
|
desc->sections[j].prot |= (phdr.p_flags & PF_X)? PROT_EXEC: 0;
|
||||||
|
|
||||||
|
__dprintf("%d: (%s) %lx, %lx, %lx, %lx, %x\n",
|
||||||
|
j, (phdr.p_type == PT_LOAD ? "PT_LOAD" : "PT_TLS"),
|
||||||
|
desc->sections[j].vaddr,
|
||||||
desc->sections[j].filesz,
|
desc->sections[j].filesz,
|
||||||
desc->sections[j].offset,
|
desc->sections[j].offset,
|
||||||
desc->sections[j].len);
|
desc->sections[j].len,
|
||||||
|
desc->sections[j].prot);
|
||||||
j++;
|
j++;
|
||||||
|
|
||||||
if (!load_addr_set) {
|
if (!load_addr_set) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <cls.h>
|
#include <cls.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <page.h>
|
#include <page.h>
|
||||||
|
#include <mman.h>
|
||||||
|
|
||||||
//#define DEBUG_PRINT_HOST
|
//#define DEBUG_PRINT_HOST
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
char **env;
|
char **env;
|
||||||
int range_npages;
|
int range_npages;
|
||||||
void *up_v;
|
void *up_v;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
sz = sizeof(struct program_load_desc)
|
sz = sizeof(struct program_load_desc)
|
||||||
+ sizeof(struct program_image_section) * 16;
|
+ sizeof(struct program_image_section) * 16;
|
||||||
@@ -88,12 +90,14 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
e = (pn->sections[i].vaddr + pn->sections[i].len
|
e = (pn->sections[i].vaddr + pn->sections[i].len
|
||||||
+ PAGE_SIZE - 1) & PAGE_MASK;
|
+ PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
range_npages = (e - s) >> PAGE_SHIFT;
|
range_npages = (e - s) >> PAGE_SHIFT;
|
||||||
|
flags = VR_NONE;
|
||||||
|
flags |= PROT_TO_VR_FLAG(pn->sections[i].prot);
|
||||||
|
|
||||||
if((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
if((up_v = ihk_mc_alloc_pages(range_npages, IHK_MC_AP_NOWAIT)) == NULL){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
up = virt_to_phys(up_v);
|
up = virt_to_phys(up_v);
|
||||||
if(add_process_memory_range(proc, s, e, up, VR_NONE) != 0){
|
if(add_process_memory_range(proc, s, e, up, flags) != 0){
|
||||||
ihk_mc_free_pages(up_v, range_npages);
|
ihk_mc_free_pages(up_v, range_npages);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -163,25 +167,26 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
(USER_END / 3) & LARGE_PAGE_MASK;
|
(USER_END / 3) & LARGE_PAGE_MASK;
|
||||||
|
|
||||||
/* Map system call stuffs */
|
/* Map system call stuffs */
|
||||||
|
flags = VR_RESERVED | VR_PROT_READ | VR_PROT_WRITE;
|
||||||
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
addr = proc->vm->region.map_start - PAGE_SIZE * SCD_RESERVED_COUNT;
|
||||||
e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT;
|
e = addr + PAGE_SIZE * DOORBELL_PAGE_COUNT;
|
||||||
if(add_process_memory_range(proc, addr, e,
|
if(add_process_memory_range(proc, addr, e,
|
||||||
cpu_local_var(scp).doorbell_pa,
|
cpu_local_var(scp).doorbell_pa,
|
||||||
VR_REMOTE | VR_RESERVED) != 0){
|
VR_REMOTE | flags) != 0){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
addr = e;
|
addr = e;
|
||||||
e = addr + PAGE_SIZE * REQUEST_PAGE_COUNT;
|
e = addr + PAGE_SIZE * REQUEST_PAGE_COUNT;
|
||||||
if(add_process_memory_range(proc, addr, e,
|
if(add_process_memory_range(proc, addr, e,
|
||||||
cpu_local_var(scp).request_pa,
|
cpu_local_var(scp).request_pa,
|
||||||
VR_REMOTE | VR_RESERVED) != 0){
|
VR_REMOTE | flags) != 0){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
addr = e;
|
addr = e;
|
||||||
e = addr + PAGE_SIZE * RESPONSE_PAGE_COUNT;
|
e = addr + PAGE_SIZE * RESPONSE_PAGE_COUNT;
|
||||||
if(add_process_memory_range(proc, addr, e,
|
if(add_process_memory_range(proc, addr, e,
|
||||||
cpu_local_var(scp).response_pa,
|
cpu_local_var(scp).response_pa,
|
||||||
VR_RESERVED) != 0){
|
flags) != 0){
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +199,8 @@ static int process_msg_prepare_process(unsigned long rphys)
|
|||||||
}
|
}
|
||||||
args_envs_p = virt_to_phys(args_envs);
|
args_envs_p = virt_to_phys(args_envs);
|
||||||
|
|
||||||
if(add_process_memory_range(proc, addr, e, args_envs_p, VR_NONE) != 0){
|
if(add_process_memory_range(proc, addr, e, args_envs_p,
|
||||||
|
VR_PROT_READ|VR_PROT_WRITE) != 0){
|
||||||
ihk_mc_free_pages(args_envs, ARGENV_PAGE_COUNT);
|
ihk_mc_free_pages(args_envs, ARGENV_PAGE_COUNT);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|||||||
34
kernel/include/mman.h
Normal file
34
kernel/include/mman.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef HEADER_MMAN_H
|
||||||
|
#define HEADER_MMAN_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* memory protection
|
||||||
|
*/
|
||||||
|
#define PROT_NONE 0
|
||||||
|
#define PROT_READ 0x01
|
||||||
|
#define PROT_WRITE 0x02
|
||||||
|
#define PROT_EXEC 0x04
|
||||||
|
|
||||||
|
/* for mprotect */
|
||||||
|
#define PROT_GROWSDOWN 0x01000000
|
||||||
|
#define PROT_GROWSUP 0x02000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mapping flags
|
||||||
|
*/
|
||||||
|
#define MAP_SHARED 0x01
|
||||||
|
#define MAP_PRIVATE 0x02
|
||||||
|
#define MAP_FIXED 0x10
|
||||||
|
#define MAP_ANONYMOUS 0x20
|
||||||
|
#define MAP_32BIT 0x40
|
||||||
|
#define MAP_GROWSDOWN 0x0100
|
||||||
|
#define MAP_DENYWRITE 0x0800
|
||||||
|
#define MAP_EXECUTABLE 0x1000
|
||||||
|
#define MAP_LOCKED 0x2000
|
||||||
|
#define MAP_NORESERVE 0x4000
|
||||||
|
#define MAP_POPULATE 0x8000
|
||||||
|
#define MAP_NONBLOCK 0x00010000
|
||||||
|
#define MAP_STACK 0x00020000
|
||||||
|
#define MAP_HUGETLB 0x00040000
|
||||||
|
|
||||||
|
#endif /* HEADER_MMAN_H */
|
||||||
@@ -13,6 +13,13 @@
|
|||||||
#define VR_IO_NOCACHE 0x100
|
#define VR_IO_NOCACHE 0x100
|
||||||
#define VR_REMOTE 0x200
|
#define VR_REMOTE 0x200
|
||||||
#define VR_DEMAND_PAGING 0x1000
|
#define VR_DEMAND_PAGING 0x1000
|
||||||
|
#define VR_PROT_NONE 0x00000000
|
||||||
|
#define VR_PROT_READ 0x00010000
|
||||||
|
#define VR_PROT_WRITE 0x00020000
|
||||||
|
#define VR_PROT_EXEC 0x00040000
|
||||||
|
#define VR_PROT_MASK 0x00070000
|
||||||
|
|
||||||
|
#define PROT_TO_VR_FLAG(prot) (((unsigned long)(prot) << 16) & VR_PROT_MASK)
|
||||||
|
|
||||||
#define PS_RUNNING 0x1
|
#define PS_RUNNING 0x1
|
||||||
#define PS_INTERRUPTIBLE 0x2
|
#define PS_INTERRUPTIBLE 0x2
|
||||||
@@ -32,7 +39,6 @@
|
|||||||
struct vm_range {
|
struct vm_range {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
unsigned long start, end;
|
unsigned long start, end;
|
||||||
unsigned long phys;
|
|
||||||
unsigned long flag;
|
unsigned long flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,6 +107,8 @@ int add_process_memory_range(struct process *process,
|
|||||||
unsigned long phys, unsigned long flag);
|
unsigned long phys, unsigned long flag);
|
||||||
int remove_process_memory_range(
|
int remove_process_memory_range(
|
||||||
struct process *process, unsigned long start, unsigned long end);
|
struct process *process, unsigned long start, unsigned long end);
|
||||||
|
struct vm_range *lookup_process_memory_range(
|
||||||
|
struct process *proc, uintptr_t start, uintptr_t end);
|
||||||
int remove_process_region(struct process *proc,
|
int remove_process_region(struct process *proc,
|
||||||
unsigned long start, unsigned long end);
|
unsigned long start, unsigned long end);
|
||||||
struct program_load_desc;
|
struct program_load_desc;
|
||||||
|
|||||||
@@ -82,7 +82,11 @@ struct program_image_section {
|
|||||||
unsigned long len;
|
unsigned long len;
|
||||||
unsigned long remote_pa;
|
unsigned long remote_pa;
|
||||||
unsigned long filesz, offset;
|
unsigned long filesz, offset;
|
||||||
|
int prot;
|
||||||
|
int padding;
|
||||||
|
#if 0
|
||||||
void *source;
|
void *source;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct program_load_desc {
|
struct program_load_desc {
|
||||||
|
|||||||
119
kernel/process.c
119
kernel/process.c
@@ -8,6 +8,7 @@
|
|||||||
#include <cpulocal.h>
|
#include <cpulocal.h>
|
||||||
#include <auxvec.h>
|
#include <auxvec.h>
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
|
#include <mman.h>
|
||||||
|
|
||||||
//#define DEBUG_PRINT_PROCESS
|
//#define DEBUG_PRINT_PROCESS
|
||||||
|
|
||||||
@@ -104,13 +105,16 @@ extern void __host_update_process_range(struct process *process,
|
|||||||
struct vm_range *range);
|
struct vm_range *range);
|
||||||
|
|
||||||
int update_process_page_table(struct process *process,
|
int update_process_page_table(struct process *process,
|
||||||
struct vm_range *range, enum ihk_mc_pt_attribute flag)
|
struct vm_range *range, uint64_t phys,
|
||||||
|
enum ihk_mc_pt_attribute flag)
|
||||||
{
|
{
|
||||||
unsigned long p, pa = range->phys;
|
unsigned long p, pa = phys;
|
||||||
unsigned long pp;
|
unsigned long pp;
|
||||||
unsigned long flags = ihk_mc_spinlock_lock(&process->vm->page_table_lock);
|
unsigned long flags = ihk_mc_spinlock_lock(&process->vm->page_table_lock);
|
||||||
const enum ihk_mc_pt_attribute attr
|
enum ihk_mc_pt_attribute attr;
|
||||||
= flag | PTATTR_WRITABLE | PTATTR_USER | PTATTR_FOR_USER;
|
|
||||||
|
attr = flag | PTATTR_USER | PTATTR_FOR_USER;
|
||||||
|
attr |= (range->flag & VR_PROT_WRITE)? PTATTR_WRITABLE: 0;
|
||||||
|
|
||||||
p = range->start;
|
p = range->start;
|
||||||
while (p < range->end) {
|
while (p < range->end) {
|
||||||
@@ -149,7 +153,7 @@ int update_process_page_table(struct process *process,
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
pp = range->start;
|
pp = range->start;
|
||||||
pa = range->phys;
|
pa = phys;
|
||||||
while(pp < p){
|
while(pp < p){
|
||||||
#ifdef USE_LARGE_PAGES
|
#ifdef USE_LARGE_PAGES
|
||||||
if ((p & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
if ((p & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
||||||
@@ -180,7 +184,6 @@ int remove_process_memory_range(struct process *process, unsigned long start, un
|
|||||||
struct vm_range *next;
|
struct vm_range *next;
|
||||||
int error;
|
int error;
|
||||||
unsigned long freestart;
|
unsigned long freestart;
|
||||||
unsigned long freephys;
|
|
||||||
unsigned long freesize;
|
unsigned long freesize;
|
||||||
struct vm_range *freerange;
|
struct vm_range *freerange;
|
||||||
struct vm_range *newrange;
|
struct vm_range *newrange;
|
||||||
@@ -198,7 +201,6 @@ int remove_process_memory_range(struct process *process, unsigned long start, un
|
|||||||
if (start <= range->start) {
|
if (start <= range->start) {
|
||||||
/* partial or whole delete from range->start */
|
/* partial or whole delete from range->start */
|
||||||
freestart = range->start;
|
freestart = range->start;
|
||||||
freephys = range->phys;
|
|
||||||
freesize = end - range->start;
|
freesize = end - range->start;
|
||||||
|
|
||||||
if (freesize >= (range->end - range->start)) {
|
if (freesize >= (range->end - range->start)) {
|
||||||
@@ -208,13 +210,11 @@ int remove_process_memory_range(struct process *process, unsigned long start, un
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
range->start += freesize;
|
range->start += freesize;
|
||||||
range->phys += freesize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (range->end <= end) {
|
else if (range->end <= end) {
|
||||||
/* partial delete up to range->end */
|
/* partial delete up to range->end */
|
||||||
freestart = start;
|
freestart = start;
|
||||||
freephys = range->phys + (start - range->start);
|
|
||||||
freesize = range->end - start;
|
freesize = range->end - start;
|
||||||
|
|
||||||
range->end = start;
|
range->end = start;
|
||||||
@@ -222,7 +222,6 @@ int remove_process_memory_range(struct process *process, unsigned long start, un
|
|||||||
else {
|
else {
|
||||||
/* delete the middle part of the 'range' */
|
/* delete the middle part of the 'range' */
|
||||||
freestart = start;
|
freestart = start;
|
||||||
freephys = range->phys + (start - range->start);
|
|
||||||
freesize = end - start;
|
freesize = end - start;
|
||||||
|
|
||||||
newrange = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
newrange = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||||
@@ -232,27 +231,36 @@ int remove_process_memory_range(struct process *process, unsigned long start, un
|
|||||||
}
|
}
|
||||||
newrange->start = end;
|
newrange->start = end;
|
||||||
newrange->end = range->end;
|
newrange->end = range->end;
|
||||||
newrange->phys = range->phys + (end - range->start);
|
|
||||||
newrange->flag = range->flag;
|
newrange->flag = range->flag;
|
||||||
list_add_tail(&newrange->list, &vm->vm_range_list);
|
list_add_tail(&newrange->list, &vm->vm_range_list);
|
||||||
|
|
||||||
range->end = start;
|
range->end = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: traverse page table entries and release physical memory area if present
|
if (freesize > 0) {
|
||||||
then mark the page table entry non-present */
|
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED))) {
|
||||||
if (freesize > 0 && !(range->flag & VR_DEMAND_PAGING)) {
|
/* clear page table and free physical pages */
|
||||||
dkprintf("remove_process_memory_range,remove_process_region\n");
|
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||||
error = remove_process_region(process, freestart, (freestart + freesize));
|
error = ihk_mc_pt_free_range(vm->page_table,
|
||||||
if (error) {
|
(void *)start, (void *)end);
|
||||||
kprintf("remove_process_memory_range:remove_process_region failed: %d\n", error);
|
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||||
/* through */
|
if (error && (error != -ENOENT)) {
|
||||||
|
kprintf("remove_process_memory_range:"
|
||||||
|
"ihk_mc_pt_free_range failed: %d\n",
|
||||||
|
error);
|
||||||
|
/* through */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED)) && !(range->flag & VR_DEMAND_PAGING)) {
|
/* clear page table */
|
||||||
dkprintf("remove_process_memory_range,ihk_mc_free_pages\n");
|
error = remove_process_region(process, freestart,
|
||||||
// XXX: need TLB shootdown?
|
(freestart + freesize));
|
||||||
ihk_mc_free_pages(phys_to_virt(freephys), freesize>>PAGE_SHIFT);
|
if (error) {
|
||||||
|
kprintf("remove_process_memory_range:"
|
||||||
|
"remove_process_region failed: %d\n",
|
||||||
|
error);
|
||||||
|
/* through */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (freerange != NULL) {
|
if (freerange != NULL) {
|
||||||
@@ -288,28 +296,29 @@ int add_process_memory_range(struct process *process,
|
|||||||
INIT_LIST_HEAD(&range->list);
|
INIT_LIST_HEAD(&range->list);
|
||||||
range->start = start;
|
range->start = start;
|
||||||
range->end = end;
|
range->end = end;
|
||||||
range->phys = phys;
|
|
||||||
range->flag = flag;
|
range->flag = flag;
|
||||||
|
|
||||||
if(range->flag & VR_DEMAND_PAGING) {
|
if(range->flag & VR_DEMAND_PAGING) {
|
||||||
dkprintf("range: 0x%lX - 0x%lX => physicall memory area is allocated on demand (%ld)\n",
|
dkprintf("range: 0x%lX - 0x%lX => physicall memory area is allocated on demand (%ld) [%lx]\n",
|
||||||
range->start, range->end, range->end - range->start);
|
range->start, range->end, range->end - range->start,
|
||||||
|
range->flag);
|
||||||
} else {
|
} else {
|
||||||
dkprintf("range: 0x%lX - 0x%lX => 0x%lX - 0x%lX (%ld)\n",
|
dkprintf("range: 0x%lX - 0x%lX => 0x%lX - 0x%lX (%ld) [%lx]\n",
|
||||||
range->start, range->end, range->phys, range->phys +
|
range->start, range->end, range->phys, range->phys +
|
||||||
range->end - range->start, range->end - range->start);
|
range->end - range->start, range->end - range->start,
|
||||||
|
range->flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag & VR_REMOTE) {
|
if (flag & VR_REMOTE) {
|
||||||
rc = update_process_page_table(process, range, IHK_PTA_REMOTE);
|
rc = update_process_page_table(process, range, phys, IHK_PTA_REMOTE);
|
||||||
} else if (flag & VR_IO_NOCACHE) {
|
} else if (flag & VR_IO_NOCACHE) {
|
||||||
rc = update_process_page_table(process, range, PTATTR_UNCACHABLE);
|
rc = update_process_page_table(process, range, phys, PTATTR_UNCACHABLE);
|
||||||
} else if(flag & VR_DEMAND_PAGING){
|
} else if(flag & VR_DEMAND_PAGING){
|
||||||
//demand paging no need to update process table now
|
//demand paging no need to update process table now
|
||||||
kprintf("demand paging do not update process page table\n");
|
kprintf("demand paging do not update process page table\n");
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
rc = update_process_page_table(process, range, 0);
|
rc = update_process_page_table(process, range, phys, 0);
|
||||||
}
|
}
|
||||||
if(rc != 0){
|
if(rc != 0){
|
||||||
kfree(range);
|
kfree(range);
|
||||||
@@ -325,13 +334,30 @@ int add_process_memory_range(struct process *process,
|
|||||||
list_add_tail(&range->list, &process->vm->vm_range_list);
|
list_add_tail(&range->list, &process->vm->vm_range_list);
|
||||||
|
|
||||||
/* Clear content! */
|
/* Clear content! */
|
||||||
if (!(flag & VR_REMOTE) && !(flag & VR_DEMAND_PAGING))
|
if (!(flag & (VR_REMOTE | VR_DEMAND_PAGING))
|
||||||
memset((void*)phys_to_virt(range->phys), 0, end - start);
|
&& ((flag & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||||
|
memset((void*)phys_to_virt(phys), 0, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vm_range *lookup_process_memory_range(struct process *proc, uintptr_t start, uintptr_t end)
|
||||||
|
{
|
||||||
|
struct vm_range *range;
|
||||||
|
|
||||||
|
if (end <= start) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(range, &proc->vm->vm_range_list, list) {
|
||||||
|
if ((start < range->end) && (range->start < end)) {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int init_process_stack(struct process *process, struct program_load_desc *pn,
|
int init_process_stack(struct process *process, struct program_load_desc *pn,
|
||||||
int argc, char **argv,
|
int argc, char **argv,
|
||||||
@@ -351,7 +377,8 @@ int init_process_stack(struct process *process, struct program_load_desc *pn,
|
|||||||
|
|
||||||
memset(stack, 0, size);
|
memset(stack, 0, size);
|
||||||
|
|
||||||
if((rc = add_process_memory_range(process, start, end, virt_to_phys(stack), VR_STACK)) != 0){
|
if ((rc = add_process_memory_range(process, start, end, virt_to_phys(stack),
|
||||||
|
VR_STACK|VR_PROT_READ|VR_PROT_WRITE)) != 0) {
|
||||||
ihk_mc_free_pages(stack, USER_STACK_NR_PAGES);
|
ihk_mc_free_pages(stack, USER_STACK_NR_PAGES);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -423,7 +450,7 @@ unsigned long extend_process_region(struct process *proc,
|
|||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
if((rc = add_process_memory_range(proc, old_aligned_end,
|
if((rc = add_process_memory_range(proc, old_aligned_end,
|
||||||
aligned_end, virt_to_phys(p), VR_NONE)) != 0){
|
aligned_end, virt_to_phys(p), flag)) != 0){
|
||||||
free_pages(p, (aligned_end - old_aligned_end) >> PAGE_SHIFT);
|
free_pages(p, (aligned_end - old_aligned_end) >> PAGE_SHIFT);
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
@@ -509,6 +536,7 @@ void free_process_memory(struct process *proc)
|
|||||||
{
|
{
|
||||||
struct vm_range *range, *next;
|
struct vm_range *range, *next;
|
||||||
struct process_vm *vm = proc->vm;
|
struct process_vm *vm = proc->vm;
|
||||||
|
int error;
|
||||||
|
|
||||||
if (vm == NULL) {
|
if (vm == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -519,17 +547,22 @@ void free_process_memory(struct process *proc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry_safe(range, next, &vm->vm_range_list,
|
ihk_mc_spinlock_lock_noirq(&proc->vm->page_table_lock);
|
||||||
list) {
|
list_for_each_entry_safe(range, next, &vm->vm_range_list, list) {
|
||||||
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED
|
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED))) {
|
||||||
| VR_DEMAND_PAGING))) {
|
error = ihk_mc_pt_free_range(vm->page_table,
|
||||||
ihk_mc_free_pages(phys_to_virt(range->phys),
|
(void *)range->start, (void *)range->end);
|
||||||
(range->end - range->start)
|
if (error && (error != -ENOENT)) {
|
||||||
>> PAGE_SHIFT);
|
kprintf("free_process_memory:"
|
||||||
|
"ihk_mc_pt_free_range(%lx,%lx) failed. %d\n",
|
||||||
|
range->start, range->end, error);
|
||||||
|
/* through */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
list_del(&range->list);
|
list_del(&range->list);
|
||||||
ihk_mc_free(range);
|
ihk_mc_free(range);
|
||||||
}
|
}
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->page_table_lock);
|
||||||
|
|
||||||
ihk_mc_pt_destroy(vm->page_table);
|
ihk_mc_pt_destroy(vm->page_table);
|
||||||
free_process(vm->owner_process);
|
free_process(vm->owner_process);
|
||||||
|
|||||||
297
kernel/syscall.c
297
kernel/syscall.c
@@ -18,6 +18,7 @@
|
|||||||
#include <affinity.h>
|
#include <affinity.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ihk/perfctr.h>
|
#include <ihk/perfctr.h>
|
||||||
|
#include <mman.h>
|
||||||
|
|
||||||
/* Headers taken from kitten LWK */
|
/* Headers taken from kitten LWK */
|
||||||
#include <lwk/stddef.h>
|
#include <lwk/stddef.h>
|
||||||
@@ -125,6 +126,14 @@ int do_syscall(struct syscall_request *req, ihk_mc_user_context_t *ctx)
|
|||||||
return res->ret;
|
return res->ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx)
|
||||||
|
{
|
||||||
|
SYSCALL_HEADER;
|
||||||
|
dkprintf("syscall_generic_forwarding(%d)\n", n);
|
||||||
|
SYSCALL_ARGS_6(D,D,D,D,D,D);
|
||||||
|
SYSCALL_FOOTER;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(open)
|
SYSCALL_DECLARE(open)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -165,6 +174,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
{
|
{
|
||||||
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
struct vm_regions *region = &cpu_local_var(current)->vm->region;
|
||||||
void *va;
|
void *va;
|
||||||
|
const unsigned long prot_flags = VR_PROT_READ | VR_PROT_WRITE | VR_PROT_EXEC;
|
||||||
|
|
||||||
dkprintf("syscall.c,mmap,addr=%lx,len=%lx,prot=%lx,flags=%x,fd=%x,offset=%lx\n",
|
dkprintf("syscall.c,mmap,addr=%lx,len=%lx,prot=%lx,flags=%x,fd=%x,offset=%lx\n",
|
||||||
ihk_mc_syscall_arg0(ctx), ihk_mc_syscall_arg1(ctx),
|
ihk_mc_syscall_arg0(ctx), ihk_mc_syscall_arg1(ctx),
|
||||||
@@ -219,7 +229,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
|
|
||||||
// add range, mapping
|
// add range, mapping
|
||||||
if(add_process_memory_range(cpu_local_var(current), s_orig, e,
|
if(add_process_memory_range(cpu_local_var(current), s_orig, e,
|
||||||
virt_to_phys((void *)(p_aligned - head_space)), VR_NONE) != 0){
|
virt_to_phys((void *)(p_aligned - head_space)), prot_flags) != 0){
|
||||||
ihk_mc_free_pages((void *)p, range_npages);
|
ihk_mc_free_pages((void *)p, range_npages);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -237,7 +247,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
pa = virt_to_phys(va);
|
pa = virt_to_phys(va);
|
||||||
|
|
||||||
// add page_table, add memory-range
|
// add page_table, add memory-range
|
||||||
if(add_process_memory_range(cpu_local_var(current), s, e, pa, VR_NONE) != 0){
|
if(add_process_memory_range(cpu_local_var(current), s, e, pa, prot_flags) != 0){
|
||||||
ihk_mc_free_pages(va, range_npages);
|
ihk_mc_free_pages(va, range_npages);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@@ -277,6 +287,8 @@ SYSCALL_DECLARE(mmap)
|
|||||||
dkprintf("syscall.c,mmap,len=%lx\n", len);
|
dkprintf("syscall.c,mmap,len=%lx\n", len);
|
||||||
|
|
||||||
unsigned long flag = 0; /* eager paging */
|
unsigned long flag = 0; /* eager paging */
|
||||||
|
|
||||||
|
flag |= VR_PROT_READ|VR_PROT_WRITE|VR_PROT_EXEC;
|
||||||
#if 1
|
#if 1
|
||||||
/* Intel OpenMP hack: it requests 128MB and munmap tail and head
|
/* Intel OpenMP hack: it requests 128MB and munmap tail and head
|
||||||
to create 64MB-aligned 64MB memory area
|
to create 64MB-aligned 64MB memory area
|
||||||
@@ -295,7 +307,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
dkprintf("syscall.c,mmap,nocache,len=%lx\n", len);
|
dkprintf("syscall.c,mmap,nocache,len=%lx\n", len);
|
||||||
region->map_end = extend_process_region(
|
region->map_end = extend_process_region(
|
||||||
cpu_local_var(current), region->map_start, map_end_aligned,
|
cpu_local_var(current), region->map_start, map_end_aligned,
|
||||||
s + len, VR_IO_NOCACHE);
|
s + len, VR_IO_NOCACHE|(flag & ~VR_DEMAND_PAGING));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -334,12 +346,13 @@ SYSCALL_DECLARE(mmap)
|
|||||||
unsigned long amt_align = 0x100000; /* takagi */
|
unsigned long amt_align = 0x100000; /* takagi */
|
||||||
unsigned long s = ((region->map_end + amt_align - 1) & ~(amt_align - 1));
|
unsigned long s = ((region->map_end + amt_align - 1) & ~(amt_align - 1));
|
||||||
unsigned long len = (ihk_mc_syscall_arg1(ctx) + PAGE_SIZE - 1) & PAGE_MASK;
|
unsigned long len = (ihk_mc_syscall_arg1(ctx) + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
|
unsigned long flag = VR_PROT_READ|VR_PROT_WRITE|VR_PROT_EXEC;
|
||||||
dkprintf("(%d),syscall.c,!MAP_FIXED,!MAP_ANONYMOUS,amt_align=%lx,s=%lx,len=%lx\n", ihk_mc_get_processor_id(), amt_align, s, len);
|
dkprintf("(%d),syscall.c,!MAP_FIXED,!MAP_ANONYMOUS,amt_align=%lx,s=%lx,len=%lx\n", ihk_mc_get_processor_id(), amt_align, s, len);
|
||||||
region->map_end =
|
region->map_end =
|
||||||
extend_process_region(cpu_local_var(current),
|
extend_process_region(cpu_local_var(current),
|
||||||
region->map_start,
|
region->map_start,
|
||||||
s,
|
s,
|
||||||
s + len, 0);
|
s + len, flag);
|
||||||
#else
|
#else
|
||||||
unsigned long s = (region->map_end + PAGE_SIZE - 1) & PAGE_MASK;
|
unsigned long s = (region->map_end + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
unsigned long len = (ihk_mc_syscall_arg1(ctx) + PAGE_SIZE - 1) & PAGE_MASK;
|
unsigned long len = (ihk_mc_syscall_arg1(ctx) + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
@@ -347,7 +360,7 @@ SYSCALL_DECLARE(mmap)
|
|||||||
extend_process_region(cpu_local_var(current),
|
extend_process_region(cpu_local_var(current),
|
||||||
region->map_start,
|
region->map_start,
|
||||||
region->map_end,
|
region->map_end,
|
||||||
s + len, 0);
|
s + len, flag);
|
||||||
#endif
|
#endif
|
||||||
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||||
if (region->map_end < s + len) { return -EINVAL; }
|
if (region->map_end < s + len) { return -EINVAL; }
|
||||||
@@ -375,16 +388,266 @@ SYSCALL_DECLARE(mmap)
|
|||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_munmap(void *addr, size_t len)
|
||||||
|
{
|
||||||
|
return remove_process_memory_range(
|
||||||
|
cpu_local_var(current), (intptr_t)addr, (intptr_t)addr+len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int search_free_space(size_t len, intptr_t hint, intptr_t *addrp)
|
||||||
|
{
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
struct vm_regions *region = &proc->vm->region;
|
||||||
|
intptr_t addr;
|
||||||
|
struct vm_range *range;
|
||||||
|
|
||||||
|
addr = hint;
|
||||||
|
for (;;) {
|
||||||
|
#ifdef USE_LARGE_PAGES
|
||||||
|
if (len >= LARGE_PAGE_SIZE) {
|
||||||
|
addr = (addr + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||||
|
}
|
||||||
|
#endif /* USE_LARGE_PAGES */
|
||||||
|
|
||||||
|
if ((region->user_end <= addr)
|
||||||
|
|| ((region->user_end - len) < addr)) {
|
||||||
|
kprintf("search_free_space:no virtual: %lx %lx %lx\n",
|
||||||
|
addr, len, region->user_end);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
range = lookup_process_memory_range(proc, addr, addr+len);
|
||||||
|
if (range == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
addr = range->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
*addrp = addr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSCALL_DECLARE(new_mmap)
|
||||||
|
{
|
||||||
|
const int supported_flags = 0
|
||||||
|
| MAP_PRIVATE // 02
|
||||||
|
| MAP_FIXED // 10
|
||||||
|
| MAP_ANONYMOUS // 20
|
||||||
|
;
|
||||||
|
const int ignored_flags = 0
|
||||||
|
#ifdef USE_NOCACHE_MMAP
|
||||||
|
| MAP_32BIT // 40
|
||||||
|
#endif /* USE_NOCACHE_MMAP */
|
||||||
|
| MAP_DENYWRITE // 0800
|
||||||
|
| MAP_NORESERVE // 4000
|
||||||
|
| MAP_STACK // 00020000
|
||||||
|
;
|
||||||
|
const int error_flags = 0
|
||||||
|
| MAP_SHARED // 01
|
||||||
|
#ifndef USE_NOCACHE_MMAP
|
||||||
|
| MAP_32BIT // 40
|
||||||
|
#endif /* ndef USE_NOCACHE_MMAP */
|
||||||
|
| MAP_GROWSDOWN // 0100
|
||||||
|
| MAP_EXECUTABLE // 1000
|
||||||
|
| MAP_LOCKED // 2000
|
||||||
|
| MAP_POPULATE // 8000
|
||||||
|
| MAP_NONBLOCK // 00010000
|
||||||
|
| MAP_HUGETLB // 00040000
|
||||||
|
;
|
||||||
|
|
||||||
|
const intptr_t addr0 = ihk_mc_syscall_arg0(ctx);
|
||||||
|
const size_t len0 = ihk_mc_syscall_arg1(ctx);
|
||||||
|
const int prot = ihk_mc_syscall_arg2(ctx);
|
||||||
|
const int flags = ihk_mc_syscall_arg3(ctx);
|
||||||
|
const int fd = ihk_mc_syscall_arg4(ctx);
|
||||||
|
const off_t off = ihk_mc_syscall_arg5(ctx);
|
||||||
|
|
||||||
|
struct process *proc = cpu_local_var(current);
|
||||||
|
struct vm_regions *region = &proc->vm->region;
|
||||||
|
intptr_t addr;
|
||||||
|
size_t len;
|
||||||
|
int error;
|
||||||
|
intptr_t npages;
|
||||||
|
int p2align;
|
||||||
|
void *p;
|
||||||
|
int vrflags;
|
||||||
|
intptr_t phys;
|
||||||
|
|
||||||
|
dkprintf("[%d]sys_mmap(%lx,%lx,%x,%x,%d,%lx)\n",
|
||||||
|
ihk_mc_get_processor_id(),
|
||||||
|
addr0, len0, prot, flags, fd, off);
|
||||||
|
|
||||||
|
/* check constants for flags */
|
||||||
|
if (1) {
|
||||||
|
int dup_flags;
|
||||||
|
|
||||||
|
dup_flags = (supported_flags & ignored_flags);
|
||||||
|
dup_flags |= (ignored_flags & error_flags);
|
||||||
|
dup_flags |= (error_flags & supported_flags);
|
||||||
|
|
||||||
|
if (dup_flags) {
|
||||||
|
kprintf("sys_mmap:duplicate flags: %lx\n", dup_flags);
|
||||||
|
kprintf("s-flags: %08x\n", supported_flags);
|
||||||
|
kprintf("i-flags: %08x\n", ignored_flags);
|
||||||
|
kprintf("e-flags: %08x\n", error_flags);
|
||||||
|
panic("sys_mmap:duplicate flags\n");
|
||||||
|
/* no return */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check arguments */
|
||||||
|
#define VALID_DUMMY_ADDR (region->user_start)
|
||||||
|
addr = (flags & MAP_FIXED)? addr0: VALID_DUMMY_ADDR;
|
||||||
|
len = (len0 + PAGE_SIZE - 1) & PAGE_MASK;
|
||||||
|
if ((addr & (PAGE_SIZE - 1))
|
||||||
|
|| (addr < region->user_start)
|
||||||
|
|| (region->user_end <= addr)
|
||||||
|
|| (len == 0)
|
||||||
|
|| (len > (region->user_end - region->user_start))
|
||||||
|
|| ((region->user_end - len) < addr)
|
||||||
|
|| !(flags & (MAP_SHARED | MAP_PRIVATE))
|
||||||
|
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
|
||||||
|
|| (off & (PAGE_SIZE - 1))) {
|
||||||
|
kprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):EINVAL\n",
|
||||||
|
addr0, len0, prot, flags, fd, off);
|
||||||
|
error = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check not supported requests */
|
||||||
|
if ((flags & error_flags)
|
||||||
|
|| (flags & ~(supported_flags | ignored_flags))) {
|
||||||
|
kprintf("sys_mmap(%lx,%lx,%x,%x,%x,%lx):unknown flags %lx\n",
|
||||||
|
addr0, len0, prot, flags, fd, off,
|
||||||
|
(flags & ~(supported_flags | ignored_flags)));
|
||||||
|
error = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
|
||||||
|
if (flags & MAP_FIXED) {
|
||||||
|
/* clear specified address range */
|
||||||
|
error = do_munmap((void *)addr, len);
|
||||||
|
if (error) {
|
||||||
|
kprintf("sys_mmap:do_munmap(%lx,%lx) failed. %d\n",
|
||||||
|
addr, len, error);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* choose mapping address */
|
||||||
|
error = search_free_space(len, region->map_end, &addr);
|
||||||
|
if (error) {
|
||||||
|
kprintf("sys_mmap:search_free_space(%lx,%lx) failed. %d\n",
|
||||||
|
len, region->map_end, error);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
region->map_end = addr + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the map */
|
||||||
|
vrflags = VR_NONE;
|
||||||
|
vrflags |= (prot & PROT_READ)? VR_PROT_READ: 0;
|
||||||
|
vrflags |= (prot & PROT_WRITE)? VR_PROT_WRITE: 0;
|
||||||
|
vrflags |= (prot & PROT_EXEC)? VR_PROT_EXEC: 0;
|
||||||
|
if (flags & MAP_ANONYMOUS) {
|
||||||
|
if (0) {
|
||||||
|
/* dummy */
|
||||||
|
}
|
||||||
|
#ifdef USE_NOCACHE_MMAP
|
||||||
|
#define X_MAP_NOCACHE MAP_32BIT
|
||||||
|
else if (flags & X_MAP_NOCACHE) {
|
||||||
|
vrflags |= VR_IO_NOCACHE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if ((len == 64*1024*1024) || (len == 128*1024*1024)) {
|
||||||
|
vrflags |= VR_DEMAND_PAGING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = NULL;
|
||||||
|
phys = 0;
|
||||||
|
if (!(vrflags & VR_DEMAND_PAGING)) {
|
||||||
|
npages = len >> PAGE_SHIFT;
|
||||||
|
p2align = PAGE_P2ALIGN;
|
||||||
|
#ifdef USE_LARGE_PAGES
|
||||||
|
if ((len >= LARGE_PAGE_SIZE)
|
||||||
|
&& ((addr & (LARGE_PAGE_SIZE - 1)) == 0)) {
|
||||||
|
p2align = LARGE_PAGE_P2ALIGN;
|
||||||
|
}
|
||||||
|
#endif /* USE_LARGE_PAGES */
|
||||||
|
p = ihk_mc_alloc_aligned_pages(npages, p2align, IHK_MC_AP_NOWAIT);
|
||||||
|
if (p == NULL) {
|
||||||
|
kprintf("sys_mmap:allocate_pages(%d,%d) failed.\n",
|
||||||
|
npages, p2align);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
error = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
phys = virt_to_phys(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = add_process_memory_range(proc, addr, addr+len, phys, vrflags);
|
||||||
|
if (error) {
|
||||||
|
kprintf("sys_mmap:add_process_memory_range"
|
||||||
|
"(%p,%lx,%lx,%lx,%lx) failed %d\n",
|
||||||
|
proc, addr, addr+len,
|
||||||
|
virt_to_phys(p), vrflags, error);
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
if (p != NULL) {
|
||||||
|
ihk_mc_free_pages(p, npages);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->vm->memory_range_lock);
|
||||||
|
|
||||||
|
/* read page with pread64() */
|
||||||
|
if (!(flags & MAP_ANONYMOUS)) {
|
||||||
|
ihk_mc_user_context_t ctx2;
|
||||||
|
ssize_t ss;
|
||||||
|
|
||||||
|
ihk_mc_syscall_arg0(&ctx2) = fd;
|
||||||
|
ihk_mc_syscall_arg1(&ctx2) = addr;
|
||||||
|
ihk_mc_syscall_arg2(&ctx2) = len;
|
||||||
|
ihk_mc_syscall_arg3(&ctx2) = off;
|
||||||
|
|
||||||
|
ss = syscall_generic_forwarding(__NR_pread64, &ctx2);
|
||||||
|
if (ss < 0) {
|
||||||
|
kprintf("sys_mmap:pread(%d,%lx,%lx,%lx) failed %ld\n",
|
||||||
|
fd, addr, len, off, (long)ss);
|
||||||
|
error = do_munmap((void *)addr, len);
|
||||||
|
if (error) {
|
||||||
|
kprintf("sys_mmap:do_munmap(%lx,%lx) failed. %d\n",
|
||||||
|
addr, len, error);
|
||||||
|
/* through */
|
||||||
|
}
|
||||||
|
error = ss;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
out:
|
||||||
|
if (error) {
|
||||||
|
kprintf("[%d]sys_mmap(%lx,%lx,%x,%x,%d,%lx): %ld %lx\n",
|
||||||
|
ihk_mc_get_processor_id(),
|
||||||
|
addr0, len0, prot, flags, fd, off, error, addr);
|
||||||
|
}
|
||||||
|
return (!error)? addr: error;
|
||||||
|
}
|
||||||
|
|
||||||
SYSCALL_DECLARE(munmap)
|
SYSCALL_DECLARE(munmap)
|
||||||
{
|
{
|
||||||
unsigned long address, len;
|
void * const addr = (void *)ihk_mc_syscall_arg0(ctx);
|
||||||
|
const size_t len = ihk_mc_syscall_arg1(ctx);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
address = ihk_mc_syscall_arg0(ctx);
|
|
||||||
len = ihk_mc_syscall_arg1(ctx);
|
|
||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||||
error = remove_process_memory_range(cpu_local_var(current), address, address+len);
|
error = do_munmap(addr, len);
|
||||||
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
@@ -420,7 +683,8 @@ SYSCALL_DECLARE(brk)
|
|||||||
/* try to extend memory region */
|
/* try to extend memory region */
|
||||||
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||||
region->brk_end = extend_process_region(cpu_local_var(current),
|
region->brk_end = extend_process_region(cpu_local_var(current),
|
||||||
region->brk_start, region->brk_end, address, 0);
|
region->brk_start, region->brk_end, address,
|
||||||
|
VR_PROT_READ|VR_PROT_WRITE);
|
||||||
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
ihk_mc_spinlock_unlock_noirq(&cpu_local_var(current)->vm->memory_range_lock);
|
||||||
dkprintf("SC(%d)[sys_brk] brk_end set to %lx\n",
|
dkprintf("SC(%d)[sys_brk] brk_end set to %lx\n",
|
||||||
ihk_mc_get_processor_id(), region->brk_end);
|
ihk_mc_get_processor_id(), region->brk_end);
|
||||||
@@ -859,14 +1123,6 @@ SYSCALL_DECLARE(pmc_reset)
|
|||||||
return ihk_mc_perfctr_reset(counter);
|
return ihk_mc_perfctr_reset(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
long syscall_generic_forwarding(int n, ihk_mc_user_context_t *ctx)
|
|
||||||
{
|
|
||||||
SYSCALL_HEADER;
|
|
||||||
dkprintf("syscall_generic_forwarding(%d)\n", n);
|
|
||||||
SYSCALL_ARGS_6(D,D,D,D,D,D);
|
|
||||||
SYSCALL_FOOTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
long syscall(int num, ihk_mc_user_context_t *ctx)
|
long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||||
{
|
{
|
||||||
long l;
|
long l;
|
||||||
@@ -918,6 +1174,7 @@ long syscall(int num, ihk_mc_user_context_t *ctx)
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void __host_update_process_range(struct process *process,
|
void __host_update_process_range(struct process *process,
|
||||||
struct vm_range *range)
|
struct vm_range *range)
|
||||||
{
|
{
|
||||||
@@ -948,4 +1205,4 @@ void __host_update_process_range(struct process *process,
|
|||||||
}
|
}
|
||||||
cpu_enable_interrupt();
|
cpu_enable_interrupt();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ int ihk_mc_pt_change_page(page_table_t pt, void *virt,
|
|||||||
int ihk_mc_pt_clear_page(page_table_t pt, void *virt);
|
int ihk_mc_pt_clear_page(page_table_t pt, void *virt);
|
||||||
int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt);
|
int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt);
|
||||||
int ihk_mc_pt_clear_range(page_table_t pt, void *start, void *end);
|
int ihk_mc_pt_clear_range(page_table_t pt, void *start, void *end);
|
||||||
|
int ihk_mc_pt_free_range(page_table_t pt, void *start, void *end);
|
||||||
int ihk_mc_pt_prepare_map(page_table_t pt, void *virt, unsigned long size,
|
int ihk_mc_pt_prepare_map(page_table_t pt, void *virt, unsigned long size,
|
||||||
enum ihk_mc_pt_prepare_flag);
|
enum ihk_mc_pt_prepare_flag);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user