Revert "trial implementation of private file mapping"

This reverts commit abe57218c4.
This commit is contained in:
NAKAMURA Gou
2013-07-26 16:44:39 +09:00
parent abe57218c4
commit 78d9d3fcd2
23 changed files with 173 additions and 1756 deletions

View File

@ -7,7 +7,6 @@
#include <errno.h>
#include <list.h>
#include <process.h>
#include <page.h>
#define ekprintf(...) kprintf(__VA_ARGS__)
@ -797,20 +796,15 @@ static int clear_range_l1(void *args0, pte_t *ptep, uint64_t base, uint64_t star
{
struct clear_range_args *args = args0;
uint64_t phys;
struct page *page;
if (*ptep == PTE_NULL) {
return -ENOENT;
}
phys = *ptep & PT_PHYSMASK;
*ptep = PTE_NULL;
*ptep = 0;
if (args->free_physical) {
page = phys_to_page(phys);
if (page && (page->mode == PM_MAPPED) && !page_unmap(page)) {
return 0;
}
ihk_mc_free_pages(phys_to_virt(phys), 1);
}
@ -823,7 +817,6 @@ static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base, uint64_t star
uint64_t phys;
struct page_table *pt;
int error;
struct page *page;
if (*ptep == PTE_NULL) {
return -ENOENT;
@ -848,15 +841,6 @@ static int clear_range_l2(void *args0, pte_t *ptep, uint64_t base, uint64_t star
*ptep = PTE_NULL;
if (args->free_physical) {
page = phys_to_page(phys);
if (page && (page->mode == PM_MAPPED)) {
if (--page->count > 0) {
/* other mapping exists */
return 0;
}
list_del(&page->list);
page->mode = PM_NONE;
}
ihk_mc_free_pages(phys_to_virt(phys),
LARGE_PAGE_SIZE/PAGE_SIZE);
}
@ -1149,369 +1133,6 @@ int ihk_mc_pt_alloc_range(page_table_t pt, void *start, void *end,
&alloc_range_l4, &attr);
}
static int lookup_pte(struct page_table *pt, uintptr_t virt, pte_t **ptepp,
uintptr_t *pgbasep, size_t *pgsizep)
{
int l4idx, l3idx, l2idx, l1idx;
GET_VIRT_INDICES(virt, l4idx, l3idx, l2idx, l1idx);
if (!(pt->entry[l4idx] & PFL4_PRESENT)) {
return -ENOENT;
}
pt = phys_to_virt(pt->entry[l4idx] & PT_PHYSMASK);
if (!(pt->entry[l3idx] & PFL3_PRESENT)) {
return -ENOENT;
}
pt = phys_to_virt(pt->entry[l3idx] & PT_PHYSMASK);
if ((pt->entry[l2idx] == PTE_NULL)
|| (pt->entry[l2idx] & PFL2_SIZE)) {
*ptepp = &pt->entry[l2idx];
*pgbasep = GET_INDICES_VIRT(l4idx, l3idx, l2idx, 0);
*pgsizep = PTL2_SIZE;
return 0;
}
pt = phys_to_virt(pt->entry[l2idx] & PT_PHYSMASK);
*ptepp = &pt->entry[l1idx];
*pgbasep = GET_INDICES_VIRT(l4idx, l3idx, l2idx, l1idx);
*pgsizep = PTL1_SIZE;
return 0;
}
int ihk_mc_pt_lookup_pte(page_table_t pt, void *virt, pte_t **ptepp, void **pgbasep, size_t *pgsizep)
{
int error;
pte_t *ptep = NULL;
uintptr_t pgbase = 0;
size_t pgsize = 0;
kprintf("ihk_mc_pt_lookup_pte(%p,%p)\n", pt, virt);
error = lookup_pte(pt, (uintptr_t)virt, &ptep, &pgbase, &pgsize);
if (error) {
kprintf("ihk_mc_pt_lookup_pte(%p,%p):lookup failed. %d\n", pt, virt, error);
goto out;
}
error = 0;
*ptepp = ptep;
*pgbasep = (void *)pgbase;
*pgsizep = pgsize;
out:
kprintf("ihk_mc_pt_lookup_pte(%p,%p): %d %p %lx %lx\n", pt, virt, error, ptep, pgbase, pgsize);
return error;
}
static int page_p2align_list[] = {
LARGE_PAGE_P2ALIGN,
PAGE_P2ALIGN,
-1,
};
int ihk_mc_pt_choose_pagesize(page_table_t pt, void *start0, void *end0,
void *fault_addr0, size_t maxpgsize, void **pgaddrp,
size_t *pgsizep, int *p2alignp)
{
const uintptr_t start = (uintptr_t)start0;
const uintptr_t end = (uintptr_t)end0;
const uintptr_t fault_addr = (uintptr_t)fault_addr0;
int ix;
int p2align;
size_t pgsize;
uintptr_t pgbase;
pte_t *ptep;
int error;
uintptr_t pga;
size_t pgs;
kprintf("ihk_mc_pt_choose_pagesize(%p,%p,%p,%p,%lx,%p,%p,%p)\n",
pt, start0, end0, fault_addr0, maxpgsize, pgaddrp,
pgsizep, p2alignp);
if ((fault_addr < start) || (end <= fault_addr)) {
kprintf("ihk_mc_pt_choose_pagesize(%p,%p,%p,%p,%lx,%p,%p,%p):"
"out of range\n",
pt, start0, end0, fault_addr0, maxpgsize,
pgaddrp, pgsizep, p2alignp);
panic("ihk_mc_pt_choose_pagesize:out of range");
}
pgs = 0;
for (ix = 0; page_p2align_list[ix] >= 0; ++ix) {
p2align = page_p2align_list[ix];
pgsize = PAGE_SIZE << p2align;
pgbase = fault_addr & ~(pgsize - 1);
if ((maxpgsize != 0) && (pgsize > maxpgsize)) {
continue;
}
if ((pgbase < start) || (end < (pgbase + pgsize))) {
continue;
}
if (pgs == 0) {
error = lookup_pte(pt, fault_addr, &ptep, &pga, &pgs);
if (error == -ENOENT) {
error = 0;
pgs = LARGE_PAGE_SIZE;
pga = fault_addr & LARGE_PAGE_MASK;
}
else if (error) {
kprintf("ihk_mc_pt_choose_pagesize("
"%p,%p,%p,%p,%lx,%p,%p,%p):"
"lookup pte failed. %d\n",
pt, start0, end0, fault_addr0,
maxpgsize, pgaddrp, pgsizep,
p2alignp, error);
goto out;
}
}
if (pgs < pgsize) {
continue;
}
error = 0;
*pgaddrp = (void *)pgbase;
*pgsizep = pgsize;
*p2alignp = p2align;
goto out;
}
kprintf("ihk_mc_pt_choose_pagesize(%p,%p,%p,%p,%lx,%p,%p,%p):"
"not reached\n",
pt, start0, end0, fault_addr0, maxpgsize, pgaddrp,
pgsizep, p2alignp);
panic("ihk_mc_pt_choose_pagesize:not reached");
out:
kprintf("ihk_mc_pt_choose_pagesize(%p,%p,%p,%p,%lx,%p,%p,%p):"
" %d %p %lx %d\n",
pt, start0, end0, fault_addr0, maxpgsize, pgaddrp,
pgsizep, p2alignp, error, *pgaddrp, *pgsizep, *p2alignp);
return error;
}
struct set_range_args {
uintptr_t phys;
enum ihk_mc_pt_attribute attr;
int padding;
uintptr_t diff;
};
int set_range_l1(void *args0, pte_t *ptep, uint64_t base, uint64_t start,
uint64_t end)
{
struct set_range_args *args = args0;
int error;
uintptr_t phys;
kprintf("set_range_l1(%p,%p,%lx,%lx,%lx)\n",
args0, ptep, base, start, end);
if (*ptep != PTE_NULL) {
kprintf("set_range_l1(%p,%p,%lx,%lx,%lx):page exists\n",
args0, ptep, base, start, end);
error = -EBUSY;
goto out;
}
phys = args->phys + (base - start);
*ptep = phys | attr_to_l1attr(args->attr);
error = 0;
out:
kprintf("set_range_l1(%p,%p,%lx,%lx,%lx): %d\n",
args0, ptep, base, start, end, error);
return error;
}
int set_range_l2(void *args0, pte_t *ptep, uint64_t base, uint64_t start,
uint64_t end)
{
struct set_range_args *args = args0;
uintptr_t phys;
int error;
struct page_table *pt;
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx)\n",
args0, ptep, base, start, end);
if (*ptep == PTE_NULL) {
if ((start <= base) && ((base + PTL2_SIZE) <= end)
&& ((args->diff & (PTL2_SIZE - 1)) == 0)) {
phys = args->phys + (base - start);
*ptep = phys | attr_to_l2attr(args->attr|PTATTR_LARGEPAGE);
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx):"
"large page\n",
args0, ptep, base, start, end);
error = 0;
goto out;
}
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
if (pt == NULL) {
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx):"
"__alloc_new_pt failed\n",
args0, ptep, base, start, end);
error = -ENOMEM;
goto out;
}
*ptep = virt_to_phys(pt) | PFL2_PDIR_ATTR;
}
else if (*ptep & PFL2_SIZE) {
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx):"
"page exists\n",
args0, ptep, base, start, end);
error = -EBUSY;
goto out;
}
else {
pt = phys_to_virt(*ptep & PT_PHYSMASK);
}
error = walk_pte_l1(pt, base, start, end, &set_range_l1, args0);
if (error) {
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx):"
"walk_pte_l1 failed. %d\n",
args0, ptep, base, start, end, error);
goto out;
}
error = 0;
out:
kprintf("set_range_l2(%p,%p,%lx,%lx,%lx): %d\n",
args0, ptep, base, start, end, error);
return error;
}
int set_range_l3(void *args0, pte_t *ptep, uint64_t base, uint64_t start,
uint64_t end)
{
struct page_table *pt;
int error;
kprintf("set_range_l3(%p,%p,%lx,%lx,%lx)\n",
args0, ptep, base, start, end);
if (*ptep == PTE_NULL) {
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
if (pt == NULL) {
kprintf("set_range_l3(%p,%p,%lx,%lx,%lx):"
"__alloc_new_pt failed\n",
args0, ptep, base, start, end);
return -ENOMEM;
}
*ptep = virt_to_phys(pt) | PFL3_PDIR_ATTR;
}
else {
pt = phys_to_virt(*ptep & PT_PHYSMASK);
}
error = walk_pte_l2(pt, base, start, end, &set_range_l2, args0);
if (error) {
kprintf("set_range_l3(%p,%p,%lx,%lx,%lx):"
"walk_pte_l2 failed. %d\n",
args0, ptep, base, start, end, error);
goto out;
}
error = 0;
out:
kprintf("set_range_l3(%p,%p,%lx,%lx,%lx): %d\n",
args0, ptep, base, start, end, error);
return error;
}
int set_range_l4(void *args0, pte_t *ptep, uint64_t base, uint64_t start,
uint64_t end)
{
struct page_table *pt;
int error;
kprintf("set_range_l4(%p,%p,%lx,%lx,%lx)\n",
args0, ptep, base, start, end);
if (*ptep == PTE_NULL) {
pt = __alloc_new_pt(IHK_MC_AP_NOWAIT);
if (pt == NULL) {
kprintf("set_range_l4(%p,%p,%lx,%lx,%lx):"
"__alloc_new_pt failed\n",
args0, ptep, base, start, end);
return -ENOMEM;
}
*ptep = virt_to_phys(pt) | PFL4_PDIR_ATTR;
}
else {
pt = phys_to_virt(*ptep & PT_PHYSMASK);
}
error = walk_pte_l3(pt, base, start, end, &set_range_l3, args0);
if (error) {
kprintf("set_range_l4(%p,%p,%lx,%lx,%lx):"
"walk_pte_l3 failed. %d\n",
args0, ptep, base, start, end, error);
goto out;
}
error = 0;
out:
kprintf("set_range_l4(%p,%p,%lx,%lx,%lx): %d\n",
args0, ptep, base, start, end, error);
return error;
}
int ihk_mc_pt_set_range(page_table_t pt, void *start, void *end,
uintptr_t phys, enum ihk_mc_pt_attribute attr)
{
int error;
struct set_range_args args;
kprintf("ihk_mc_pt_set_range(%p,%p,%p,%lx,%x)\n",
pt, start, end, phys, attr);
args.phys = phys;
args.attr = attr;
args.diff = (uintptr_t)start ^ phys;
error = walk_pte_l4(pt, 0, (uintptr_t)start, (uintptr_t)end,
&set_range_l4, &args);
if (error) {
kprintf("ihk_mc_pt_set_range(%p,%p,%p,%lx,%x):"
"walk_pte_l4 failed. %d\n",
pt, start, end, phys, attr, error);
goto out;
}
error = 0;
out:
kprintf("ihk_mc_pt_set_range(%p,%p,%p,%lx,%x): %d\n",
pt, start, end, phys, attr, error);
return error;
}
int ihk_mc_pt_set_pte(page_table_t pt, pte_t *ptep, uintptr_t phys, size_t pgsize, enum ihk_mc_pt_attribute attr)
{
kprintf("ihk_mc_pt_set_pte(%p,%p,%lx,%lx,%x):\n",
pt, ptep, phys, pgsize, attr);
switch (pgsize) {
case PTL1_SIZE:
*ptep = phys | attr_to_l1attr(attr);
break;
case PTL2_SIZE:
*ptep = phys | attr_to_l2attr(attr | PTATTR_LARGEPAGE);
break;
default:
kprintf("ihk_mc_pt_set_pte(%p,%p,%lx,%lx,%x):\n",
pt, ptep, phys, pgsize, attr);
panic("ihk_mc_pt_set_pte");
break;
}
return 0;
}
void load_page_table(struct page_table *pt)
{
unsigned long pt_addr;