|
@@ -1512,7 +1512,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|
struct page *page;
|
|
struct page *page;
|
|
pgtable_t pgtable;
|
|
pgtable_t pgtable;
|
|
pmd_t _pmd;
|
|
pmd_t _pmd;
|
|
- bool young, write, dirty;
|
|
|
|
|
|
+ bool young, write, dirty, soft_dirty;
|
|
unsigned long addr;
|
|
unsigned long addr;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
@@ -1546,6 +1546,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|
write = pmd_write(*pmd);
|
|
write = pmd_write(*pmd);
|
|
young = pmd_young(*pmd);
|
|
young = pmd_young(*pmd);
|
|
dirty = pmd_dirty(*pmd);
|
|
dirty = pmd_dirty(*pmd);
|
|
|
|
+ soft_dirty = pmd_soft_dirty(*pmd);
|
|
|
|
|
|
pmdp_huge_split_prepare(vma, haddr, pmd);
|
|
pmdp_huge_split_prepare(vma, haddr, pmd);
|
|
pgtable = pgtable_trans_huge_withdraw(mm, pmd);
|
|
pgtable = pgtable_trans_huge_withdraw(mm, pmd);
|
|
@@ -1562,6 +1563,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|
swp_entry_t swp_entry;
|
|
swp_entry_t swp_entry;
|
|
swp_entry = make_migration_entry(page + i, write);
|
|
swp_entry = make_migration_entry(page + i, write);
|
|
entry = swp_entry_to_pte(swp_entry);
|
|
entry = swp_entry_to_pte(swp_entry);
|
|
|
|
+ if (soft_dirty)
|
|
|
|
+ entry = pte_swp_mksoft_dirty(entry);
|
|
} else {
|
|
} else {
|
|
entry = mk_pte(page + i, vma->vm_page_prot);
|
|
entry = mk_pte(page + i, vma->vm_page_prot);
|
|
entry = maybe_mkwrite(entry, vma);
|
|
entry = maybe_mkwrite(entry, vma);
|
|
@@ -1569,6 +1572,8 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|
entry = pte_wrprotect(entry);
|
|
entry = pte_wrprotect(entry);
|
|
if (!young)
|
|
if (!young)
|
|
entry = pte_mkold(entry);
|
|
entry = pte_mkold(entry);
|
|
|
|
+ if (soft_dirty)
|
|
|
|
+ entry = pte_mksoft_dirty(entry);
|
|
}
|
|
}
|
|
if (dirty)
|
|
if (dirty)
|
|
SetPageDirty(page + i);
|
|
SetPageDirty(page + i);
|