diff options
| -rw-r--r-- | Documentation/vm/pagemap.txt | 2 | ||||
| -rw-r--r-- | fs/proc/task_mmu.c | 48 |
2 files changed, 31 insertions, 19 deletions
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt index 4600cbe3d6be..7587493c67f1 100644 --- a/Documentation/vm/pagemap.txt +++ b/Documentation/vm/pagemap.txt | |||
| @@ -16,7 +16,7 @@ There are three components to pagemap: | |||
| 16 | * Bits 0-4 swap type if swapped | 16 | * Bits 0-4 swap type if swapped |
| 17 | * Bits 5-54 swap offset if swapped | 17 | * Bits 5-54 swap offset if swapped |
| 18 | * Bits 55-60 page shift (page size = 1<<page shift) | 18 | * Bits 55-60 page shift (page size = 1<<page shift) |
| 19 | * Bit 61 reserved for future use | 19 | * Bit 61 page is file-page or shared-anon |
| 20 | * Bit 62 page swapped | 20 | * Bit 62 page swapped |
| 21 | * Bit 63 page present | 21 | * Bit 63 page present |
| 22 | 22 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 83ede6e3b5ec..02476f5889f1 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -700,6 +700,7 @@ struct pagemapread { | |||
| 700 | 700 | ||
| 701 | #define PM_PRESENT PM_STATUS(4LL) | 701 | #define PM_PRESENT PM_STATUS(4LL) |
| 702 | #define PM_SWAP PM_STATUS(2LL) | 702 | #define PM_SWAP PM_STATUS(2LL) |
| 703 | #define PM_FILE PM_STATUS(1LL) | ||
| 703 | #define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT) | 704 | #define PM_NOT_PRESENT PM_PSHIFT(PAGE_SHIFT) |
| 704 | #define PM_END_OF_BUFFER 1 | 705 | #define PM_END_OF_BUFFER 1 |
| 705 | 706 | ||
| @@ -733,22 +734,33 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end, | |||
| 733 | return err; | 734 | return err; |
| 734 | } | 735 | } |
| 735 | 736 | ||
| 736 | static u64 swap_pte_to_pagemap_entry(pte_t pte) | 737 | static void pte_to_pagemap_entry(pagemap_entry_t *pme, |
| 738 | struct vm_area_struct *vma, unsigned long addr, pte_t pte) | ||
| 737 | { | 739 | { |
| 738 | swp_entry_t e = pte_to_swp_entry(pte); | 740 | u64 frame, flags; |
| 739 | return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); | 741 | struct page *page = NULL; |
| 740 | } | 742 | |
| 741 | 743 | if (pte_present(pte)) { | |
| 742 | static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte) | 744 | frame = pte_pfn(pte); |
| 743 | { | 745 | flags = PM_PRESENT; |
| 744 | if (is_swap_pte(pte)) | 746 | page = vm_normal_page(vma, addr, pte); |
| 745 | *pme = make_pme(PM_PFRAME(swap_pte_to_pagemap_entry(pte)) | 747 | } else if (is_swap_pte(pte)) { |
| 746 | | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP); | 748 | swp_entry_t entry = pte_to_swp_entry(pte); |
| 747 | else if (pte_present(pte)) | 749 | |
| 748 | *pme = make_pme(PM_PFRAME(pte_pfn(pte)) | 750 | frame = swp_type(entry) | |
| 749 | | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT); | 751 | (swp_offset(entry) << MAX_SWAPFILES_SHIFT); |
| 750 | else | 752 | flags = PM_SWAP; |
| 753 | if (is_migration_entry(entry)) | ||
| 754 | page = migration_entry_to_page(entry); | ||
| 755 | } else { | ||
| 751 | *pme = make_pme(PM_NOT_PRESENT); | 756 | *pme = make_pme(PM_NOT_PRESENT); |
| 757 | return; | ||
| 758 | } | ||
| 759 | |||
| 760 | if (page && !PageAnon(page)) | ||
| 761 | flags |= PM_FILE; | ||
| 762 | |||
| 763 | *pme = make_pme(PM_PFRAME(frame) | PM_PSHIFT(PAGE_SHIFT) | flags); | ||
| 752 | } | 764 | } |
| 753 | 765 | ||
| 754 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 766 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| @@ -815,7 +827,7 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
| 815 | if (vma && (vma->vm_start <= addr) && | 827 | if (vma && (vma->vm_start <= addr) && |
| 816 | !is_vm_hugetlb_page(vma)) { | 828 | !is_vm_hugetlb_page(vma)) { |
| 817 | pte = pte_offset_map(pmd, addr); | 829 | pte = pte_offset_map(pmd, addr); |
| 818 | pte_to_pagemap_entry(&pme, *pte); | 830 | pte_to_pagemap_entry(&pme, vma, addr, *pte); |
| 819 | /* unmap before userspace copy */ | 831 | /* unmap before userspace copy */ |
| 820 | pte_unmap(pte); | 832 | pte_unmap(pte); |
| 821 | } | 833 | } |
| @@ -869,11 +881,11 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask, | |||
| 869 | * For each page in the address space, this file contains one 64-bit entry | 881 | * For each page in the address space, this file contains one 64-bit entry |
| 870 | * consisting of the following: | 882 | * consisting of the following: |
| 871 | * | 883 | * |
| 872 | * Bits 0-55 page frame number (PFN) if present | 884 | * Bits 0-54 page frame number (PFN) if present |
| 873 | * Bits 0-4 swap type if swapped | 885 | * Bits 0-4 swap type if swapped |
| 874 | * Bits 5-55 swap offset if swapped | 886 | * Bits 5-54 swap offset if swapped |
| 875 | * Bits 55-60 page shift (page size = 1<<page shift) | 887 | * Bits 55-60 page shift (page size = 1<<page shift) |
| 876 | * Bit 61 reserved for future use | 888 | * Bit 61 page is file-page or shared-anon |
| 877 | * Bit 62 page swapped | 889 | * Bit 62 page swapped |
| 878 | * Bit 63 page present | 890 | * Bit 63 page present |
| 879 | * | 891 | * |
