anolis: mm: pgtable_share: check pte for rare page_vma_mapped_walk() caller
ANBZ: #6632 page_mapped_in_vma() will check whether the page has been mapped into ptes by calling page_vma_mapped_walk(). The new flag PVMW_SHARED_PGTABLE_CHECK marked to tell page_vma_mapped_walk() check to pte level, and return right value. The normal VMAs does not need this flag. (NOTE: page_mapped_in_vma() only be called on anonymous VMAs, but we need this patch for security). Signed-off-by: Rongwei Wang <rongwei.wang@linux.alibaba.com> Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reviewed-by: Xu Yu <xuyu@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/2550
This commit is contained in:
parent
7b5dcb167d
commit
3298aba75d
|
@ -215,6 +215,7 @@ void try_to_unmap_zeropage(struct page *page, enum ttu_flags flags);
|
|||
#ifdef CONFIG_PAGETABLE_SHARE
|
||||
/* Avoid unnecessary page walk for shared pgtable */
|
||||
#define PVMW_SHARED_PGTABLE (1 << 3)
|
||||
#define PVMW_SHARED_PGTABLE_CHECK (1 << 4)
|
||||
#endif
|
||||
|
||||
struct page_vma_mapped_walk {
|
||||
|
|
|
@ -166,7 +166,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
|
|||
|
||||
#ifdef CONFIG_PAGETABLE_SHARE
|
||||
if ((vma_is_pgtable_shared(pvmw->vma) || vma_is_pgtable_shadow(pvmw->vma)) &&
|
||||
!(pvmw->flags & PVMW_SHARED_PGTABLE))
|
||||
!(pvmw->flags & (PVMW_SHARED_PGTABLE | PVMW_SHARED_PGTABLE_CHECK)))
|
||||
return not_found(pvmw);
|
||||
#endif
|
||||
|
||||
|
@ -228,6 +228,19 @@ restart:
|
|||
if (vma_is_pgtable_shared(pvmw->vma)) {
|
||||
pvmw->ptl = pmd_lock(mm, pvmw->pmd);
|
||||
if (!pmd_none(pmde)) {
|
||||
if (pvmw->flags & PVMW_SHARED_PGTABLE_CHECK) {
|
||||
pte_t *ptep, pte;
|
||||
|
||||
ptep = pte_offset_map(pvmw->pmd, pvmw->address);
|
||||
pte = READ_ONCE(*ptep);
|
||||
if (!pte_present(pte) ||
|
||||
!pfn_is_match(pvmw->page, pte_pfn(pte))) {
|
||||
pte_unmap(ptep);
|
||||
return false;
|
||||
}
|
||||
pte_unmap(ptep);
|
||||
}
|
||||
|
||||
pvmw->pte = (pte_t *)pvmw->pmd;
|
||||
pvmw->pmd = NULL;
|
||||
return true;
|
||||
|
@ -335,6 +348,12 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
|
|||
pvmw.address = vma_address(page, vma);
|
||||
if (pvmw.address == -EFAULT)
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_PAGETABLE_SHARE
|
||||
if (vma_is_pgtable_shared(vma) || vma_is_pgtable_shadow(vma))
|
||||
pvmw.flags |= PVMW_SHARED_PGTABLE_CHECK;
|
||||
#endif
|
||||
|
||||
if (!page_vma_mapped_walk(&pvmw))
|
||||
return 0;
|
||||
page_vma_mapped_walk_done(&pvmw);
|
||||
|
|
Loading…
Reference in New Issue