#ifndef HAVE_ARCH_ALLOC_PAGE
 static inline void arch_alloc_page(struct page *page, int order) { }
 #endif
+#ifndef HAVE_ARCH_MAKE_PAGE_ACCESSIBLE
+static inline int arch_make_page_accessible(struct page *page)
+{
+       return 0;
+}
+#endif
 
 struct page *
 __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred_nid,
 
        struct page *page;
        spinlock_t *ptl;
        pte_t *ptep, pte;
+       int ret;
 
        /* FOLL_GET and FOLL_PIN are mutually exclusive. */
        if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
                if (is_zero_pfn(pte_pfn(pte))) {
                        page = pte_page(pte);
                } else {
-                       int ret;
-
                        ret = follow_pfn_pte(vma, address, ptep, flags);
                        page = ERR_PTR(ret);
                        goto out;
        }
 
        if (flags & FOLL_SPLIT && PageTransCompound(page)) {
-               int ret;
                get_page(page);
                pte_unmap_unlock(ptep, ptl);
                lock_page(page);
                page = ERR_PTR(-ENOMEM);
                goto out;
        }
+       /*
+        * We need to make the page accessible if and only if we are going
+        * to access its content (the FOLL_PIN case).  Please see
+        * Documentation/core-api/pin_user_pages.rst for details.
+        */
+       if (flags & FOLL_PIN) {
+               ret = arch_make_page_accessible(page);
+               if (ret) {
+                       unpin_user_page(page);
+                       page = ERR_PTR(ret);
+                       goto out;
+               }
+       }
        if (flags & FOLL_TOUCH) {
                if ((flags & FOLL_WRITE) &&
                    !pte_dirty(pte) && !PageDirty(page))
 
                VM_BUG_ON_PAGE(compound_head(page) != head, page);
 
+               /*
+                * We need to make the page accessible if and only if we are
+                * going to access its content (the FOLL_PIN case).  Please
+                * see Documentation/core-api/pin_user_pages.rst for
+                * details.
+                */
+               if (flags & FOLL_PIN) {
+                       ret = arch_make_page_accessible(page);
+                       if (ret) {
+                               unpin_user_page(page);
+                               goto pte_unmap;
+                       }
+               }
                SetPageReferenced(page);
                pages[*nr] = page;
                (*nr)++;
 
 int __test_set_page_writeback(struct page *page, bool keep_write)
 {
        struct address_space *mapping = page_mapping(page);
-       int ret;
+       int ret, access_ret;
 
        lock_page_memcg(page);
        if (mapping && mapping_use_writeback_tags(mapping)) {
                inc_zone_page_state(page, NR_ZONE_WRITE_PENDING);
        }
        unlock_page_memcg(page);
+       access_ret = arch_make_page_accessible(page);
+       /*
+        * If writeback has been triggered on a page that cannot be made
+        * accessible, it is too late to recover here.
+        */
+       VM_BUG_ON_PAGE(access_ret != 0, page);
+
        return ret;
 
 }