add rollback when ihk_mc_pt_set_page returns error
This commit is contained in:
@ -621,6 +621,11 @@ int ihk_mc_pt_clear_page(page_table_t pt, void *virt)
|
||||
return __clear_pt_page(pt, virt, 0);
|
||||
}
|
||||
|
||||
int ihk_mc_pt_clear_large_page(page_table_t pt, void *virt)
|
||||
{
|
||||
return __clear_pt_page(pt, virt, 1);
|
||||
}
|
||||
|
||||
void load_page_table(struct page_table *pt)
|
||||
{
|
||||
unsigned long pt_addr;
|
||||
|
||||
@ -112,7 +112,7 @@ static int update_process_page_table(struct process *process,
|
||||
struct vm_range *range, enum ihk_mc_pt_attribute flag)
|
||||
{
|
||||
unsigned long p, pa = range->phys;
|
||||
|
||||
unsigned long pp;
|
||||
unsigned long flags = ihk_mc_spinlock_lock(&process->vm->page_table_lock);
|
||||
p = range->start;
|
||||
while (p < range->end) {
|
||||
@ -125,8 +125,7 @@ static int update_process_page_table(struct process *process,
|
||||
|
||||
if (ihk_mc_pt_set_large_page(process->vm->page_table, (void *)p,
|
||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
||||
kprintf("ERROR:setting large page for 0x%lX -> 0x%lX\n", p, pa);
|
||||
panic("");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dkprintf("large page set for 0x%lX -> 0x%lX\n", p, pa);
|
||||
@ -138,8 +137,7 @@ static int update_process_page_table(struct process *process,
|
||||
#endif
|
||||
if(ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0){
|
||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||
return -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
pa += PAGE_SIZE;
|
||||
@ -150,6 +148,31 @@ static int update_process_page_table(struct process *process,
|
||||
}
|
||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
pp = range->start;
|
||||
pa = range->phys;
|
||||
while(pp < p){
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if ((p & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
||||
(pa & (LARGE_PAGE_SIZE - 1)) == 0 &&
|
||||
(range->end - p) >= LARGE_PAGE_SIZE) {
|
||||
ihk_mc_pt_clear_large_page(process->vm->page_table, (void *)pp);
|
||||
pa += LARGE_PAGE_SIZE;
|
||||
pp += LARGE_PAGE_SIZE;
|
||||
}
|
||||
else{
|
||||
#endif
|
||||
ihk_mc_pt_clear_page(process->vm->page_table, (void *)pp);
|
||||
pa += PAGE_SIZE;
|
||||
pp += PAGE_SIZE;
|
||||
#ifdef USE_LARGE_PAGES
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@ -91,6 +91,7 @@ int ihk_mc_pt_set_large_page(page_table_t pt, void *virt,
|
||||
int ihk_mc_pt_change_page(page_table_t pt, void *virt,
|
||||
enum ihk_mc_pt_attribute);
|
||||
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_prepare_map(page_table_t pt, void *virt, unsigned long size,
|
||||
enum ihk_mc_pt_prepare_flag);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user