|
@@ -949,6 +949,7 @@ struct pagemapread {
|
|
|
#define PM_PFRAME_BITS 55
|
|
|
#define PM_PFRAME_MASK GENMASK_ULL(PM_PFRAME_BITS - 1, 0)
|
|
|
#define PM_SOFT_DIRTY BIT_ULL(55)
|
|
|
+#define PM_MMAP_EXCLUSIVE BIT_ULL(56)
|
|
|
#define PM_FILE BIT_ULL(61)
|
|
|
#define PM_SWAP BIT_ULL(62)
|
|
|
#define PM_PRESENT BIT_ULL(63)
|
|
@@ -1036,6 +1037,8 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
|
|
|
|
|
|
if (page && !PageAnon(page))
|
|
|
flags |= PM_FILE;
|
|
|
+ if (page && page_mapcount(page) == 1)
|
|
|
+ flags |= PM_MMAP_EXCLUSIVE;
|
|
|
if (vma->vm_flags & VM_SOFTDIRTY)
|
|
|
flags |= PM_SOFT_DIRTY;
|
|
|
|
|
@@ -1066,6 +1069,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
|
|
|
* This if-check is just to prepare for future implementation.
|
|
|
*/
|
|
|
if (pmd_present(pmd)) {
|
|
|
+ struct page *page = pmd_page(pmd);
|
|
|
+
|
|
|
+ if (page_mapcount(page) == 1)
|
|
|
+ flags |= PM_MMAP_EXCLUSIVE;
|
|
|
+
|
|
|
flags |= PM_PRESENT;
|
|
|
if (pm->show_pfn)
|
|
|
frame = pmd_pfn(pmd) +
|
|
@@ -1131,6 +1139,9 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask,
|
|
|
if (!PageAnon(page))
|
|
|
flags |= PM_FILE;
|
|
|
|
|
|
+ if (page_mapcount(page) == 1)
|
|
|
+ flags |= PM_MMAP_EXCLUSIVE;
|
|
|
+
|
|
|
flags |= PM_PRESENT;
|
|
|
if (pm->show_pfn)
|
|
|
frame = pte_pfn(pte) +
|
|
@@ -1163,7 +1174,8 @@ static int pagemap_hugetlb_range(pte_t *ptep, unsigned long hmask,
|
|
|
* Bits 0-4 swap type if swapped
|
|
|
* Bits 5-54 swap offset if swapped
|
|
|
* Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
|
|
|
- * Bits 56-60 zero
|
|
|
+ * Bit 56 page exclusively mapped
|
|
|
+ * Bits 57-60 zero
|
|
|
* Bit 61 page is file-page or shared-anon
|
|
|
* Bit 62 page swapped
|
|
|
* Bit 63 page present
|