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);
|
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)
|
void load_page_table(struct page_table *pt)
|
||||||
{
|
{
|
||||||
unsigned long pt_addr;
|
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)
|
struct vm_range *range, enum ihk_mc_pt_attribute flag)
|
||||||
{
|
{
|
||||||
unsigned long p, pa = range->phys;
|
unsigned long p, pa = range->phys;
|
||||||
|
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);
|
||||||
p = range->start;
|
p = range->start;
|
||||||
while (p < range->end) {
|
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,
|
if (ihk_mc_pt_set_large_page(process->vm->page_table, (void *)p,
|
||||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0) {
|
||||||
kprintf("ERROR:setting large page for 0x%lX -> 0x%lX\n", p, pa);
|
goto err;
|
||||||
panic("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dkprintf("large page set for 0x%lX -> 0x%lX\n", p, pa);
|
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
|
#endif
|
||||||
if(ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
if(ihk_mc_pt_set_page(process->vm->page_table, (void *)p,
|
||||||
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0){
|
pa, PTATTR_WRITABLE | PTATTR_USER | flag) != 0){
|
||||||
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
goto err;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pa += PAGE_SIZE;
|
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);
|
ihk_mc_spinlock_unlock(&process->vm->page_table_lock, flags);
|
||||||
return 0;
|
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
|
#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,
|
int ihk_mc_pt_change_page(page_table_t pt, void *virt,
|
||||||
enum ihk_mc_pt_attribute);
|
enum ihk_mc_pt_attribute);
|
||||||
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_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