userfaultfd.c (7677f7fd8be76659cd2d0db8ff4093bbb51c20e5) | userfaultfd.c (f619147104c8ea71e120e4936d2b68ec11a1e527) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * fs/userfaultfd.c 4 * 5 * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org> 6 * Copyright (C) 2008-2009 Red Hat, Inc. 7 * Copyright (C) 2015 Red Hat, Inc. 8 * --- 1473 unchanged lines hidden (view full) --- 1482 1483 /* 1484 * Declare the WP ioctl only if the WP mode is 1485 * specified and all checks passed with the range 1486 */ 1487 if (!(uffdio_register.mode & UFFDIO_REGISTER_MODE_WP)) 1488 ioctls_out &= ~((__u64)1 << _UFFDIO_WRITEPROTECT); 1489 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * fs/userfaultfd.c 4 * 5 * Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org> 6 * Copyright (C) 2008-2009 Red Hat, Inc. 7 * Copyright (C) 2015 Red Hat, Inc. 8 * --- 1473 unchanged lines hidden (view full) --- 1482 1483 /* 1484 * Declare the WP ioctl only if the WP mode is 1485 * specified and all checks passed with the range 1486 */ 1487 if (!(uffdio_register.mode & UFFDIO_REGISTER_MODE_WP)) 1488 ioctls_out &= ~((__u64)1 << _UFFDIO_WRITEPROTECT); 1489 |
1490 /* CONTINUE ioctl is only supported for MINOR ranges. */ 1491 if (!(uffdio_register.mode & UFFDIO_REGISTER_MODE_MINOR)) 1492 ioctls_out &= ~((__u64)1 << _UFFDIO_CONTINUE); 1493 |
|
1490 /* 1491 * Now that we scanned all vmas we can already tell 1492 * userland which ioctls methods are guaranteed to 1493 * succeed on this range. 1494 */ 1495 if (put_user(ioctls_out, &user_uffdio_register->ioctls)) 1496 ret = -EFAULT; 1497 } --- 337 unchanged lines hidden (view full) --- 1835 if (!mode_wp && !mode_dontwake) { 1836 range.start = uffdio_wp.range.start; 1837 range.len = uffdio_wp.range.len; 1838 wake_userfault(ctx, &range); 1839 } 1840 return ret; 1841} 1842 | 1494 /* 1495 * Now that we scanned all vmas we can already tell 1496 * userland which ioctls methods are guaranteed to 1497 * succeed on this range. 1498 */ 1499 if (put_user(ioctls_out, &user_uffdio_register->ioctls)) 1500 ret = -EFAULT; 1501 } --- 337 unchanged lines hidden (view full) --- 1839 if (!mode_wp && !mode_dontwake) { 1840 range.start = uffdio_wp.range.start; 1841 range.len = uffdio_wp.range.len; 1842 wake_userfault(ctx, &range); 1843 } 1844 return ret; 1845} 1846 |
1847static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg) 1848{ 1849 __s64 ret; 1850 struct uffdio_continue uffdio_continue; 1851 struct uffdio_continue __user *user_uffdio_continue; 1852 struct userfaultfd_wake_range range; 1853 1854 user_uffdio_continue = (struct uffdio_continue __user *)arg; 1855 1856 ret = -EAGAIN; 1857 if (READ_ONCE(ctx->mmap_changing)) 1858 goto out; 1859 1860 ret = -EFAULT; 1861 if (copy_from_user(&uffdio_continue, user_uffdio_continue, 1862 /* don't copy the output fields */ 1863 sizeof(uffdio_continue) - (sizeof(__s64)))) 1864 goto out; 1865 1866 ret = validate_range(ctx->mm, &uffdio_continue.range.start, 1867 uffdio_continue.range.len); 1868 if (ret) 1869 goto out; 1870 1871 ret = -EINVAL; 1872 /* double check for wraparound just in case. */ 1873 if (uffdio_continue.range.start + uffdio_continue.range.len <= 1874 uffdio_continue.range.start) { 1875 goto out; 1876 } 1877 if (uffdio_continue.mode & ~UFFDIO_CONTINUE_MODE_DONTWAKE) 1878 goto out; 1879 1880 if (mmget_not_zero(ctx->mm)) { 1881 ret = mcopy_continue(ctx->mm, uffdio_continue.range.start, 1882 uffdio_continue.range.len, 1883 &ctx->mmap_changing); 1884 mmput(ctx->mm); 1885 } else { 1886 return -ESRCH; 1887 } 1888 1889 if (unlikely(put_user(ret, &user_uffdio_continue->mapped))) 1890 return -EFAULT; 1891 if (ret < 0) 1892 goto out; 1893 1894 /* len == 0 would wake all */ 1895 BUG_ON(!ret); 1896 range.len = ret; 1897 if (!(uffdio_continue.mode & UFFDIO_CONTINUE_MODE_DONTWAKE)) { 1898 range.start = uffdio_continue.range.start; 1899 wake_userfault(ctx, &range); 1900 } 1901 ret = range.len == uffdio_continue.range.len ? 0 : -EAGAIN; 1902 1903out: 1904 return ret; 1905} 1906 |
|
1843static inline unsigned int uffd_ctx_features(__u64 user_features) 1844{ 1845 /* 1846 * For the current set of features the bits just coincide 1847 */ 1848 return (unsigned int)user_features; 1849} 1850 --- 71 unchanged lines hidden (view full) --- 1922 ret = userfaultfd_copy(ctx, arg); 1923 break; 1924 case UFFDIO_ZEROPAGE: 1925 ret = userfaultfd_zeropage(ctx, arg); 1926 break; 1927 case UFFDIO_WRITEPROTECT: 1928 ret = userfaultfd_writeprotect(ctx, arg); 1929 break; | 1907static inline unsigned int uffd_ctx_features(__u64 user_features) 1908{ 1909 /* 1910 * For the current set of features the bits just coincide 1911 */ 1912 return (unsigned int)user_features; 1913} 1914 --- 71 unchanged lines hidden (view full) --- 1986 ret = userfaultfd_copy(ctx, arg); 1987 break; 1988 case UFFDIO_ZEROPAGE: 1989 ret = userfaultfd_zeropage(ctx, arg); 1990 break; 1991 case UFFDIO_WRITEPROTECT: 1992 ret = userfaultfd_writeprotect(ctx, arg); 1993 break; |
1994 case UFFDIO_CONTINUE: 1995 ret = userfaultfd_continue(ctx, arg); 1996 break; |
|
1930 } 1931 return ret; 1932} 1933 1934#ifdef CONFIG_PROC_FS 1935static void userfaultfd_show_fdinfo(struct seq_file *m, struct file *f) 1936{ 1937 struct userfaultfd_ctx *ctx = f->private_data; --- 104 unchanged lines hidden --- | 1997 } 1998 return ret; 1999} 2000 2001#ifdef CONFIG_PROC_FS 2002static void userfaultfd_show_fdinfo(struct seq_file *m, struct file *f) 2003{ 2004 struct userfaultfd_ctx *ctx = f->private_data; --- 104 unchanged lines hidden --- |