/* * While a process runs, Xen pins its pagetables, which means that the * hypervisor forces it to be read-only, and it controls all updates * to it. This means that all pagetable updates have to go via the * hypervisor, which is moderately expensive. * * Since we're pulling the pagetable down, we switch to use init_mm, * unpin old process pagetable and mark it all read-write, which * allows further operations on it to be simple memory accesses. * * The only subtle point is that another CPU may be still using the * pagetable because of lazy tlb flushing. This means we need need to * switch all CPUs off this pagetable before we can unpin it. */ void xen_exit_mmap(struct mm_struct *mm) { get_cpu(); /* make sure we don't move around */ drop_mm_ref(mm); put_cpu(); spin_lock(&mm->page_table_lock); /* pgd may not be pinned in the error exit path of execve */ if (PagePinned(virt_to_page(mm->pgd))) xen_pgd_unpin(mm->pgd); spin_unlock(&mm->page_table_lock); }
static bool xen_page_pinned(void *ptr) { struct page *page = virt_to_page(ptr); return PagePinned(page); }