From 010932f53f5ccd3084552e34e3f909a231af5947 Mon Sep 17 00:00:00 2001 From: ZhangPeng Date: Thu, 18 May 2023 19:16:15 +0800 Subject: [PATCH] userswap: fix VM_BUG_ON() in handle_userfault() hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM -------------------------------- When CONFIG_VM_BUG_ON=y and userswap feature is used, there is a kernel BUG in handle_userfault(). VM_BUG_ON() didn't allow more than one reason flag. Fix this by skipping VM_BUG_ON() if reason is VM_UFFD_MISSING|VM_USWAP. Signed-off-by: ZhangPeng --- fs/userfaultfd.c | 4 ++++ include/linux/userswap.h | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index ef51ed87ef38..4b20f0fd949e 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -406,8 +406,12 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason) BUG_ON(ctx->mm != mm); +#ifdef CONFIG_USERSWAP + VM_BUG_ON(uswap_vm_flag_bug_on(reason)); +#else VM_BUG_ON(reason & ~(VM_UFFD_MISSING|VM_UFFD_WP)); VM_BUG_ON(!(reason & VM_UFFD_MISSING) ^ !!(reason & VM_UFFD_WP)); +#endif if (ctx->features & UFFD_FEATURE_SIGBUS) goto out; diff --git a/include/linux/userswap.h b/include/linux/userswap.h index 82cc79584e43..6c96cef2ec9b 100644 --- a/include/linux/userswap.h +++ b/include/linux/userswap.h @@ -47,6 +47,18 @@ static inline bool uswap_validate_mremap_flags(unsigned long flags) return true; } +/* When CONFIG_USERSWAP=y, VM_UFFD_MISSING|VM_USWAP is right; + * 0 or > 1 flags set is a bug; we expect exactly 1. + */ +static inline bool uswap_vm_flag_bug_on(unsigned long reason) +{ + if (reason & ~(VM_UFFD_MISSING | VM_UFFD_WP | VM_USWAP)) + return true; + if (reason & VM_USWAP) + return !(reason & VM_UFFD_MISSING) || reason & ~(VM_USWAP|VM_UFFD_MISSING); + return !(reason & VM_UFFD_MISSING) ^ !!(reason & VM_UFFD_WP); +} + #endif /* CONFIG_USERSWAP */ #endif /* _LINUX_USERSWAP_H */ -- GitLab