Message ID | 20221021163703.3218176-36-jthoughton@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | hugetlb: introduce HugeTLB high-granularity mapping | expand |
On Fri, Oct 21, 2022 at 04:36:51PM +0000, James Houghton wrote: > @@ -1990,6 +1990,17 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx, > ~(UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM); > #ifndef CONFIG_HUGETLB_HIGH_GRANULARITY_MAPPING > uffdio_api.features &= ~UFFD_FEATURE_MINOR_HUGETLBFS_HGM; > +#else > + > + ret = -EINVAL; > + if ((uffdio_api.features & UFFD_FEATURE_MINOR_HUGETLBFS_HGM) && > + !(uffdio_api.features & UFFD_FEATURE_EXACT_ADDRESS)) This check needs to be done upon "features" or "ctx_features", rather than "uffdio_api.features". The latter is the one we'll report to the user only. > + /* > + * UFFD_FEATURE_MINOR_HUGETLBFS_HGM is mostly > + * useless without UFFD_FEATURE_EXACT_ADDRESS, > + * so require userspace to provide both. > + */ > + goto err_out; > #endif /* CONFIG_HUGETLB_HIGH_GRANULARITY_MAPPING */ > #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */ > > -- > 2.38.0.135.g90850a2211-goog > >
On Thu, Dec 22, 2022 at 4:47 PM Peter Xu <peterx@redhat.com> wrote: > > On Fri, Oct 21, 2022 at 04:36:51PM +0000, James Houghton wrote: > > @@ -1990,6 +1990,17 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx, > > ~(UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM); > > #ifndef CONFIG_HUGETLB_HIGH_GRANULARITY_MAPPING > > uffdio_api.features &= ~UFFD_FEATURE_MINOR_HUGETLBFS_HGM; > > +#else > > + > > + ret = -EINVAL; > > + if ((uffdio_api.features & UFFD_FEATURE_MINOR_HUGETLBFS_HGM) && > > + !(uffdio_api.features & UFFD_FEATURE_EXACT_ADDRESS)) > > This check needs to be done upon "features" or "ctx_features", rather than > "uffdio_api.features". The latter is the one we'll report to the user only. Ack, thanks Peter. I'm going to drop this patch given the API change (switching to MADV_SPLIT). - James
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 0204108e3882..c8f21f53e37d 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -1990,6 +1990,17 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx, ~(UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM); #ifndef CONFIG_HUGETLB_HIGH_GRANULARITY_MAPPING uffdio_api.features &= ~UFFD_FEATURE_MINOR_HUGETLBFS_HGM; +#else + + ret = -EINVAL; + if ((uffdio_api.features & UFFD_FEATURE_MINOR_HUGETLBFS_HGM) && + !(uffdio_api.features & UFFD_FEATURE_EXACT_ADDRESS)) + /* + * UFFD_FEATURE_MINOR_HUGETLBFS_HGM is mostly + * useless without UFFD_FEATURE_EXACT_ADDRESS, + * so require userspace to provide both. + */ + goto err_out; #endif /* CONFIG_HUGETLB_HIGH_GRANULARITY_MAPPING */ #endif /* CONFIG_HAVE_ARCH_USERFAULTFD_MINOR */
To avoid bugs in userspace, we require that userspace provide UFFD_FEATURE_EXACT_ADDRESS when using UFFD_FEATURE_MINOR_HUGETLBFS_HGM, otherwise UFFDIO_API will fail with EINVAL. The potential confusion is this: without EXACT_ADDRESS, the address given in the userfaultfd message will be rounded down to the hugepage size. Userspace may think that, because they're using HGM, just UFFDIO_CONTINUE the interval [address, address+PAGE_SIZE), but for faults that didn't occur in the first base page of the hugepage, this won't resolve the fault. The only choice it has in this scenario is to UFFDIO_CONTINUE the interval [address, address+hugepage_size), which negates the purpose of using HGM in the first place. By requiring userspace to provide UFFD_FEATURE_EXACT_ADDRESS, there is no rounding, and userspace now has the information it needs to appropriately resolve the fault. Another potential solution here is to change the behavior when UFFD_FEATURE_EXACT_ADDRESS is not provided: when HGM is enabled, start rounding to PAGE_SIZE instead of to the hugepage size. I think requiring UFFD_FEATURE_EXACT_ADDRESS is cleaner. Signed-off-by: James Houghton <jthoughton@google.com> --- fs/userfaultfd.c | 11 +++++++++++ 1 file changed, 11 insertions(+)