On 22 Apr 2023 14:37:05 +0100 Lorenzo Stoakes <lstoakes@xxxxxxxxx> > @@ -110,7 +110,8 @@ int qib_get_user_pages(unsigned long start_page, size_t num_pages, > for (got = 0; got < num_pages; got += ret) { > ret = pin_user_pages(start_page + got * PAGE_SIZE, > num_pages - got, > - FOLL_LONGTERM | FOLL_WRITE, > + FOLL_LONGTERM | FOLL_WRITE | > + FOLL_ALLOW_BROKEN_FILE_MAPPING, > p + got, NULL); > if (ret < 0) { > mmap_read_unlock(current->mm); [...] > +/* > + * Writing to file-backed mappings using GUP is a fundamentally broken operation > + * as kernel write access to GUP mappings may not adhere to the semantics > + * expected by a file system. > + * > + * In most instances we disallow this broken behaviour, however there are some > + * exceptions to this enforced here. > + */ > +static inline bool can_write_file_mapping(struct vm_area_struct *vma, > + unsigned long gup_flags) > +{ > + struct file *file = vma->vm_file; > + > + /* If we aren't pinning then no problematic write can occur. */ > + if (!(gup_flags & (FOLL_GET | FOLL_PIN))) > + return true; > + > + /* Special mappings should pose no problem. */ > + if (!file) > + return true; > + > + /* Has the caller explicitly indicated this case is acceptable? */ > + if (gup_flags & FOLL_ALLOW_BROKEN_FILE_MAPPING) > + return true; Does the caller mean that PUP for DMA is no longer breaking writeback? > + > + /* shmem and hugetlb mappings do not have problematic semantics. */ > + return vma_is_shmem(vma) || is_file_hugepages(file); > +}