ContiguousPTE[7/12] modify ihk_mc_pt_set_range

Change-Id: Ib38530ce64a01f21107e0a6a73de7c54f214eb5a
This commit is contained in:
TOIDA,Suguru
2018-11-30 09:18:21 +09:00
committed by Masamichi Takagi
parent 24d3da32ed
commit c319fe08a4
8 changed files with 62 additions and 22 deletions

View File

@@ -2274,6 +2274,7 @@ struct set_range_args {
uintptr_t diff;
struct process_vm *vm;
struct vm_range *range; /* To find pages we don't need to call memory_stat_rss_add() */
int overwrite;
};
int set_range_middle(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
@@ -2289,7 +2290,7 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
dkprintf("set_range_l1(%lx,%lx,%lx)\n", base, start, end);
if (!ptl1_null(ptep)) {
if (!args->overwrite && !ptl1_null(ptep)) {
error = -EBUSY;
ekprintf("set_range_l1(%lx,%lx,%lx):page exists. %d %lx\n",
base, start, end, error, *ptep);
@@ -2298,6 +2299,21 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
}
phys = args->phys + (base - start);
if (__page_offset(base, PTL1_CONT_SIZE) == 0) { //check head pte
uintptr_t next_addr = base + PTL1_CONT_SIZE;
if (end < next_addr) {
next_addr = end;
}
// set contiguous bit until the next head pte
// if phys is aligned and range does not end early.
if (__page_offset(phys | next_addr, PTL1_CONT_SIZE) == 0) {
args->attr[0] |= PTE_CONT;
} else {
args->attr[0] &= ~PTE_CONT;
}
}
pte = phys | args->attr[0];
ptl1_set(ptep, pte);
@@ -2334,10 +2350,11 @@ int set_range_middle(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
walk_pte_fn_t* callback;
unsigned long pgsize;
unsigned long pgshift;
unsigned long cont_pgsize;
} table[] = {
{walk_pte_l1, set_range_l1, PTL2_SIZE, PTL2_SHIFT}, /*PTL2: second*/
{walk_pte_l2, set_range_l2, PTL3_SIZE, PTL3_SHIFT}, /*PTL3: first*/
{walk_pte_l3, set_range_l3, PTL4_SIZE, PTL4_SHIFT}, /*PTL4: zero*/
{walk_pte_l1, set_range_l1, PTL2_SIZE, PTL2_SHIFT, PTL2_CONT_SIZE}, /*PTL2: second*/
{walk_pte_l2, set_range_l2, PTL3_SIZE, PTL3_SHIFT, PTL3_CONT_SIZE}, /*PTL3: first*/
{walk_pte_l3, set_range_l3, PTL4_SIZE, PTL4_SHIFT, PTL4_CONT_SIZE}, /*PTL4: zero*/
};
const struct table tbl = table[level-2];
@@ -2349,7 +2366,7 @@ int set_range_middle(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
dkprintf("set_range_middle(%lx,%lx,%lx,%d)\n", base, start, end, level);
retry:
if (ptl_null(ptep, level)) {
if (ptl_null(ptep, level) || (args->overwrite && ptl_type_page(ptep, level))) {
pte_t pte;
uintptr_t phys;
if (level == 2 || (level == 3 && FIRST_LEVEL_BLOCK_SUPPORT)) {
@@ -2358,7 +2375,28 @@ retry:
&& (!args->pgshift
|| (args->pgshift == tbl.pgshift))) {
phys = args->phys + (base - start);
ptl_set(ptep, phys | args->attr[level-1], level);
//check head pte
if (__page_offset(base, tbl.cont_pgsize) == 0) {
uintptr_t next_addr = base +
tbl.cont_pgsize;
if (end < next_addr) {
next_addr = end;
}
// set contiguous bit until the
// next head pte if phys is aligned
// and range does not end early.
if (__page_offset(phys | next_addr, tbl.cont_pgsize) == 0) {
args->attr[level-1] |= PTE_CONT;
} else {
args->attr[level-1] &= ~PTE_CONT;
}
}
ptl_set(ptep, phys | args->attr[level-1],
level);
error = 0;
dkprintf("set_range_middle(%lx,%lx,%lx,%d):"
"large page. %d %lx\n",
@@ -2422,7 +2460,7 @@ out:
int ihk_mc_pt_set_range(page_table_t pt, struct process_vm *vm, void *start,
void *end, uintptr_t phys, enum ihk_mc_pt_attribute attr,
int pgshift, struct vm_range *range)
int pgshift, struct vm_range *range, int overwrite)
{
const struct table {
walk_pte_t* walk;
@@ -2446,6 +2484,7 @@ int ihk_mc_pt_set_range(page_table_t pt, struct process_vm *vm, void *start,
args.vm = vm;
args.pgshift = pgshift;
args.range = range;
args.overwrite = overwrite;
// conversion
switch (CONFIG_ARM64_PGTABLE_LEVELS)
@@ -2698,7 +2737,7 @@ static int move_one_page(void *arg0, page_table_t pt, pte_t *ptep,
attr = apte & ~PT_PHYSMASK;
error = ihk_mc_pt_set_range(pt, args->vm, (void *)dest,
(void *)(dest + pgsize), phys, attr, pgshift, args->range);
(void *)(dest + pgsize), phys, attr, pgshift, args->range, 0);
if (error) {
kprintf("move_one_page(%p,%p,%p %#lx,%p,%d):"
"set failed. %d\n",