diff options
| author | Dan Williams <dan.j.williams@intel.com> | 2017-10-23 10:20:00 -0400 |
|---|---|---|
| committer | Dan Williams <dan.j.williams@intel.com> | 2018-01-19 19:50:53 -0500 |
| commit | 785a3fab4adbf91b2189c928a59ae219c54ba95e (patch) | |
| tree | 7a3f3342c336eb99cbc7ddbe09741af78d7e99b2 | |
| parent | 77dd66a3c67c93ab401ccc15efff25578be281fd (diff) | |
mm, dax: introduce pfn_t_special()
In support of removing the VM_MIXEDMAP indication from DAX VMAs,
introduce pfn_t_special() for drivers to indicate that _PAGE_SPECIAL
should be used for DAX ptes. This also helps identify drivers like
dccssblk that only want to use DAX in a read-only fashion without
get_user_pages() support.
Ideally we could delete axonram and dcssblk DAX support, but if we need
to keep it better make it explicit that axonram and dcssblk only support
a sub-set of DAX due to missing _PAGE_DEVMAP support.
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
| -rw-r--r-- | arch/powerpc/sysdev/axonram.c | 2 | ||||
| -rw-r--r-- | drivers/s390/block/dcssblk.c | 3 | ||||
| -rw-r--r-- | include/linux/pfn_t.h | 13 | ||||
| -rw-r--r-- | mm/memory.c | 16 |
4 files changed, 31 insertions, 3 deletions
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 1b307c80b401..cdbb0e59b3d3 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c | |||
| @@ -151,7 +151,7 @@ __axon_ram_direct_access(struct axon_ram_bank *bank, pgoff_t pgoff, long nr_page | |||
| 151 | resource_size_t offset = pgoff * PAGE_SIZE; | 151 | resource_size_t offset = pgoff * PAGE_SIZE; |
| 152 | 152 | ||
| 153 | *kaddr = (void *) bank->io_addr + offset; | 153 | *kaddr = (void *) bank->io_addr + offset; |
| 154 | *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV); | 154 | *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV|PFN_SPECIAL); |
| 155 | return (bank->size - offset) / PAGE_SIZE; | 155 | return (bank->size - offset) / PAGE_SIZE; |
| 156 | } | 156 | } |
| 157 | 157 | ||
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 6aaefb780436..9cae08b36b80 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
| @@ -916,7 +916,8 @@ __dcssblk_direct_access(struct dcssblk_dev_info *dev_info, pgoff_t pgoff, | |||
| 916 | 916 | ||
| 917 | dev_sz = dev_info->end - dev_info->start + 1; | 917 | dev_sz = dev_info->end - dev_info->start + 1; |
| 918 | *kaddr = (void *) dev_info->start + offset; | 918 | *kaddr = (void *) dev_info->start + offset; |
| 919 | *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV); | 919 | *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), |
| 920 | PFN_DEV|PFN_SPECIAL); | ||
| 920 | 921 | ||
| 921 | return (dev_sz - offset) / PAGE_SIZE; | 922 | return (dev_sz - offset) / PAGE_SIZE; |
| 922 | } | 923 | } |
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h index 43b1d7648e82..a03c2642a87c 100644 --- a/include/linux/pfn_t.h +++ b/include/linux/pfn_t.h | |||
| @@ -15,8 +15,10 @@ | |||
| 15 | #define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2)) | 15 | #define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2)) |
| 16 | #define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3)) | 16 | #define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3)) |
| 17 | #define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4)) | 17 | #define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4)) |
| 18 | #define PFN_SPECIAL (1ULL << (BITS_PER_LONG_LONG - 5)) | ||
| 18 | 19 | ||
| 19 | #define PFN_FLAGS_TRACE \ | 20 | #define PFN_FLAGS_TRACE \ |
| 21 | { PFN_SPECIAL, "SPECIAL" }, \ | ||
| 20 | { PFN_SG_CHAIN, "SG_CHAIN" }, \ | 22 | { PFN_SG_CHAIN, "SG_CHAIN" }, \ |
| 21 | { PFN_SG_LAST, "SG_LAST" }, \ | 23 | { PFN_SG_LAST, "SG_LAST" }, \ |
| 22 | { PFN_DEV, "DEV" }, \ | 24 | { PFN_DEV, "DEV" }, \ |
| @@ -120,4 +122,15 @@ pud_t pud_mkdevmap(pud_t pud); | |||
| 120 | #endif | 122 | #endif |
| 121 | #endif /* __HAVE_ARCH_PTE_DEVMAP */ | 123 | #endif /* __HAVE_ARCH_PTE_DEVMAP */ |
| 122 | 124 | ||
| 125 | #ifdef __HAVE_ARCH_PTE_SPECIAL | ||
| 126 | static inline bool pfn_t_special(pfn_t pfn) | ||
| 127 | { | ||
| 128 | return (pfn.val & PFN_SPECIAL) == PFN_SPECIAL; | ||
| 129 | } | ||
| 130 | #else | ||
| 131 | static inline bool pfn_t_special(pfn_t pfn) | ||
| 132 | { | ||
| 133 | return false; | ||
| 134 | } | ||
| 135 | #endif /* __HAVE_ARCH_PTE_SPECIAL */ | ||
| 123 | #endif /* _LINUX_PFN_T_H_ */ | 136 | #endif /* _LINUX_PFN_T_H_ */ |
diff --git a/mm/memory.c b/mm/memory.c index ca5674cbaff2..46b6c33b7f04 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1897,12 +1897,26 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, | |||
| 1897 | } | 1897 | } |
| 1898 | EXPORT_SYMBOL(vm_insert_pfn_prot); | 1898 | EXPORT_SYMBOL(vm_insert_pfn_prot); |
| 1899 | 1899 | ||
| 1900 | static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn) | ||
| 1901 | { | ||
| 1902 | /* these checks mirror the abort conditions in vm_normal_page */ | ||
| 1903 | if (vma->vm_flags & VM_MIXEDMAP) | ||
| 1904 | return true; | ||
| 1905 | if (pfn_t_devmap(pfn)) | ||
| 1906 | return true; | ||
| 1907 | if (pfn_t_special(pfn)) | ||
| 1908 | return true; | ||
| 1909 | if (is_zero_pfn(pfn_t_to_pfn(pfn))) | ||
| 1910 | return true; | ||
| 1911 | return false; | ||
| 1912 | } | ||
| 1913 | |||
| 1900 | static int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, | 1914 | static int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, |
| 1901 | pfn_t pfn, bool mkwrite) | 1915 | pfn_t pfn, bool mkwrite) |
| 1902 | { | 1916 | { |
| 1903 | pgprot_t pgprot = vma->vm_page_prot; | 1917 | pgprot_t pgprot = vma->vm_page_prot; |
| 1904 | 1918 | ||
| 1905 | BUG_ON(!(vma->vm_flags & VM_MIXEDMAP)); | 1919 | BUG_ON(!vm_mixed_ok(vma, pfn)); |
| 1906 | 1920 | ||
| 1907 | if (addr < vma->vm_start || addr >= vma->vm_end) | 1921 | if (addr < vma->vm_start || addr >= vma->vm_end) |
| 1908 | return -EFAULT; | 1922 | return -EFAULT; |
