The patch titled Subject: mm/hmm: remove HMM_PFN_READ flag and ignore peculiar architecture has been added to the -mm tree. Its filename is mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Jérôme Glisse <jglisse@xxxxxxxxxx> Subject: mm/hmm: remove HMM_PFN_READ flag and ignore peculiar architecture Only peculiar architecture allow write without read thus assume that any valid pfn do allow for read. Note we do not care for write only because it does make sense with thing like atomic compare and exchange or any other operations that allow you to get the memory value through them. Link: http://lkml.kernel.org/r/20180323005527.758-8-jglisse@xxxxxxxxxx Signed-off-by: Jérôme Glisse <jglisse@xxxxxxxxxx> Reviewed-by: John Hubbard <jhubbard@xxxxxxxxxx> Cc: Evgeny Baskakov <ebaskakov@xxxxxxxxxx> Cc: Ralph Campbell <rcampbell@xxxxxxxxxx> Cc: Mark Hairgrove <mhairgrove@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/hmm.h | 16 ++++++--------- mm/hmm.c | 44 ++++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 19 deletions(-) diff -puN include/linux/hmm.h~mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2 include/linux/hmm.h --- a/include/linux/hmm.h~mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2 +++ a/include/linux/hmm.h @@ -83,8 +83,7 @@ struct hmm; * hmm_pfn_t - HMM uses its own pfn type to keep several flags per page * * Flags: - * HMM_PFN_VALID: pfn is valid - * HMM_PFN_READ: CPU page table has read permission set + * HMM_PFN_VALID: pfn is valid. It has, at least, read permission. * HMM_PFN_WRITE: CPU page table has write permission set * HMM_PFN_ERROR: corresponding CPU page table entry points to poisoned memory * HMM_PFN_EMPTY: corresponding CPU page table entry is pte_none() @@ -97,13 +96,12 @@ struct hmm; typedef unsigned long hmm_pfn_t; #define HMM_PFN_VALID (1 << 0) -#define HMM_PFN_READ (1 << 1) -#define HMM_PFN_WRITE (1 << 2) -#define HMM_PFN_ERROR (1 << 3) -#define HMM_PFN_EMPTY (1 << 4) -#define HMM_PFN_SPECIAL (1 << 5) -#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 6) -#define HMM_PFN_SHIFT 7 +#define HMM_PFN_WRITE (1 << 1) +#define HMM_PFN_ERROR (1 << 2) +#define HMM_PFN_EMPTY (1 << 3) +#define HMM_PFN_SPECIAL (1 << 4) +#define HMM_PFN_DEVICE_UNADDRESSABLE (1 << 5) +#define HMM_PFN_SHIFT 6 /* * hmm_pfn_t_to_page() - return struct page pointed to by a valid hmm_pfn_t diff -puN mm/hmm.c~mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2 mm/hmm.c --- a/mm/hmm.c~mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2 +++ a/mm/hmm.c @@ -417,11 +417,9 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp, hmm_pfn_t *pfns = range->pfns; unsigned long addr = start, i; bool write_fault; - hmm_pfn_t flag; pte_t *ptep; i = (addr - range->start) >> PAGE_SHIFT; - flag = vma->vm_flags & VM_READ ? HMM_PFN_READ : 0; write_fault = hmm_vma_walk->fault & hmm_vma_walk->write; again: @@ -433,6 +431,7 @@ again: if (pmd_devmap(*pmdp) || pmd_trans_huge(*pmdp)) { unsigned long pfn; + hmm_pfn_t flag = 0; pmd_t pmd; /* @@ -497,7 +496,6 @@ again: } else if (write_fault) goto fault; pfns[i] |= HMM_PFN_DEVICE_UNADDRESSABLE; - pfns[i] |= flag; } else if (is_migration_entry(entry)) { if (hmm_vma_walk->fault) { pte_unmap(ptep); @@ -517,7 +515,7 @@ again: if (write_fault && !pte_write(pte)) goto fault; - pfns[i] = hmm_pfn_t_from_pfn(pte_pfn(pte)) | flag; + pfns[i] = hmm_pfn_t_from_pfn(pte_pfn(pte)); pfns[i] |= pte_write(pte) ? HMM_PFN_WRITE : 0; continue; @@ -534,7 +532,8 @@ fault: /* * hmm_vma_get_pfns() - snapshot CPU page table for a range of virtual addresses * @range: range being snapshotted - * Returns: -EINVAL if invalid argument, -ENOMEM out of memory, 0 success + * Returns: -EINVAL if invalid argument, -ENOMEM out of memory, -EPERM invalid + * vma permission, 0 success * * This snapshots the CPU page table for a range of virtual addresses. Snapshot * validity is tracked by range struct. See hmm_vma_range_done() for further @@ -573,6 +572,17 @@ int hmm_vma_get_pfns(struct hmm_range *r if (!hmm->mmu_notifier.ops) return -EINVAL; + if (!(vma->vm_flags & VM_READ)) { + /* + * If vma do not allow read access, then assume that it does + * not allow write access, either. Architecture that allow + * write without read access are not supported by HMM, because + * operations such has atomic access would not work. + */ + hmm_pfns_clear(range->pfns, range->start, range->end); + return -EPERM; + } + /* Initialize range to track CPU page table update */ spin_lock(&hmm->lock); range->valid = true; @@ -686,6 +696,9 @@ EXPORT_SYMBOL(hmm_vma_range_done); * goto retry; * case 0: * break; + * case -ENOMEM: + * case -EINVAL: + * case -EPERM: * default: * // Handle error ! * up_read(&mm->mmap_sem) @@ -727,11 +740,16 @@ int hmm_vma_fault(struct hmm_range *rang if (!hmm->mmu_notifier.ops) return -EINVAL; - /* Initialize range to track CPU page table update */ - spin_lock(&hmm->lock); - range->valid = true; - list_add_rcu(&range->list, &hmm->ranges); - spin_unlock(&hmm->lock); + if (!(vma->vm_flags & VM_READ)) { + /* + * If vma do not allow read access, then assume that it does + * not allow write access, either. Architecture that allow + * write without read access are not supported by HMM, because + * operations such has atomic access would not work. + */ + hmm_pfns_clear(range->pfns, range->start, range->end); + return -EPERM; + } /* FIXME support hugetlb fs */ if (is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_SPECIAL)) { @@ -739,6 +757,12 @@ int hmm_vma_fault(struct hmm_range *rang return 0; } + /* Initialize range to track CPU page table update */ + spin_lock(&hmm->lock); + range->valid = true; + list_add_rcu(&range->list, &hmm->ranges); + spin_unlock(&hmm->lock); + hmm_vma_walk.fault = true; hmm_vma_walk.write = write; hmm_vma_walk.block = block; _ Patches currently in -mm which might be from jglisse@xxxxxxxxxx are mm-hmm-fix-header-file-if-else-endif-maze-v2.patch mm-hmm-unregister-mmu_notifier-when-last-hmm-client-quit-v3.patch mm-hmm-hmm_pfns_bad-was-accessing-wrong-struct.patch mm-hmm-use-struct-for-hmm_vma_fault-hmm_vma_get_pfns-parameters-v2.patch mm-hmm-remove-hmm_pfn_read-flag-and-ignore-peculiar-architecture-v2.patch mm-hmm-use-uint64_t-for-hmm-pfn-instead-of-defining-hmm_pfn_t-to-ulong-v2.patch mm-hmm-cleanup-special-vma-handling-vm_special.patch mm-hmm-do-not-differentiate-between-empty-entry-or-missing-directory-v3.patch mm-hmm-rename-hmm_pfn_device_unaddressable-to-hmm_pfn_device_private.patch mm-hmm-move-hmm_pfns_clear-closer-to-where-it-is-use.patch mm-hmm-factor-out-pte-and-pmd-handling-to-simplify-hmm_vma_walk_pmd-v2.patch mm-hmm-change-hmm_vma_fault-to-allow-write-fault-on-page-basis.patch mm-hmm-use-device-driver-encoding-for-hmm-pfn-v2.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html