Messages in this thread Patch in this message | | | From | Khalid Aziz <> | Subject | [RFC PATCH v7 13/16] xpfo, mm: optimize spinlock usage in xpfo_kunmap | Date | Thu, 10 Jan 2019 14:09:45 -0700 |
| |
From: Julian Stecklina <jsteckli@amazon.de>
Only the xpfo_kunmap call that needs to actually unmap the page needs to be serialized. We need to be careful to handle the case, where after the atomic decrement of the mapcount, a xpfo_kmap increased the mapcount again. In this case, we can safely skip modifying the page table.
Model-checked with up to 4 concurrent callers with Spin.
Signed-off-by: Julian Stecklina <jsteckli@amazon.de> Cc: x86@kernel.org Cc: kernel-hardening@lists.openwall.com Cc: Vasileios P. Kemerlis <vpk@cs.columbia.edu> Cc: Juerg Haefliger <juerg.haefliger@canonical.com> Cc: Tycho Andersen <tycho@docker.com> Cc: Marco Benatto <marco.antonio.780@gmail.com> Cc: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com> --- mm/xpfo.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/mm/xpfo.c b/mm/xpfo.c index cbfeafc2f10f..dbf20efb0499 100644 --- a/mm/xpfo.c +++ b/mm/xpfo.c @@ -149,22 +149,24 @@ void xpfo_kunmap(void *kaddr, struct page *page) if (!PageXpfoUser(page)) return; - spin_lock(&page->xpfo_lock); - /* * The page is to be allocated back to user space, so unmap it from the * kernel, flush the TLB and tag it as a user page. */ if (atomic_dec_return(&page->xpfo_mapcount) == 0) { -#ifdef CONFIG_XPFO_DEBUG - BUG_ON(PageXpfoUnmapped(page)); -#endif - SetPageXpfoUnmapped(page); - set_kpte(kaddr, page, __pgprot(0)); - xpfo_cond_flush_kernel_tlb(page, 0); - } + spin_lock(&page->xpfo_lock); - spin_unlock(&page->xpfo_lock); + /* + * In the case, where we raced with kmap after the + * atomic_dec_return, we must not nuke the mapping. + */ + if (atomic_read(&page->xpfo_mapcount) == 0) { + SetPageXpfoUnmapped(page); + set_kpte(kaddr, page, __pgprot(0)); + xpfo_cond_flush_kernel_tlb(page, 0); + } + spin_unlock(&page->xpfo_lock); + } } EXPORT_SYMBOL(xpfo_kunmap); -- 2.17.1
| |