@@ -115,11 +115,18 @@ static int clean_record_pte(pte_t *pte, unsigned long addr,
static int wp_clean_pmd_entry(pmd_t *pmd, unsigned long addr, unsigned long end,
struct mm_walk *walk)
{
- /* Dirty-tracking should be handled on the pte level */
pmd_t pmdval = pmd_read_atomic(pmd);
- if (pmd_trans_huge(pmdval) || pmd_devmap(pmdval))
- WARN_ON(pmd_write(pmdval) || pmd_dirty(pmdval));
+ /*
+ * Dirty-tracking should be handled on the pte level, and write-
+ * enabled huge PMDS should never have been created. Warn on those.
+ * Read-only huge PMDS can't be dirty so we just skip them.
+ */
+ if (pmd_trans_huge(pmdval) || pmd_devmap(pmdval)) {
+ if (WARN_ON(pmd_write(pmdval) || pmd_dirty(pmdval)))
+ return 0;
+ return PAGE_WALK_CONTINUE;
+ }
return 0;
}