]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag '9p-fixes-for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Mar 2024 21:53:56 +0000 (14:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Mar 2024 21:53:56 +0000 (14:53 -0700)
Pull 9p fixes from Eric Van Hensbergen:
 "Two of these fix syzbot reported issues, and the other fixes a unused
  variable in some configurations"

* tag '9p-fixes-for-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
  fs/9p: fix uninitialized values during inode evict
  fs/9p: remove redundant pointer v9ses
  fs/9p: fix uaf in in v9fs_stat2inode_dotl

55 files changed:
.mailmap
MAINTAINERS
arch/arm/include/asm/mman.h [new file with mode: 0644]
arch/hexagon/kernel/vmlinux.lds.S
arch/parisc/include/asm/mman.h [new file with mode: 0644]
arch/x86/include/asm/crash_reserve.h
crypto/asymmetric_keys/mscode_parser.c
crypto/asymmetric_keys/pkcs7_parser.c
crypto/asymmetric_keys/public_key.c
crypto/asymmetric_keys/signature.c
crypto/asymmetric_keys/x509_cert_parser.c
crypto/testmgr.h
drivers/crypto/intel/iaa/iaa_crypto_main.c
drivers/pwm/pwm-img.c
drivers/uio/uio.c
drivers/uio/uio_dmem_genirq.c
drivers/uio/uio_pruss.c
fs/binfmt_elf_fdpic.c
fs/btrfs/block-group.c
fs/btrfs/extent_io.c
fs/btrfs/extent_map.c
fs/btrfs/scrub.c
fs/btrfs/volumes.c
fs/btrfs/zoned.c
fs/exec.c
fs/gfs2/bmap.c
include/linux/mman.h
include/linux/oid_registry.h
include/linux/pagevec.h
init/initramfs.c
kernel/crash_reserve.c
kernel/module/Kconfig
kernel/printk/printk.c
kernel/sys.c
kernel/time/posix-clock.c
kernel/trace/trace_probe.c
mm/filemap.c
mm/memory.c
mm/page_owner.c
mm/shmem_quota.c
mm/userfaultfd.c
mm/zswap.c
tools/Makefile
tools/testing/selftests/exec/Makefile
tools/testing/selftests/exec/binfmt_script.py
tools/testing/selftests/exec/execveat.c
tools/testing/selftests/exec/load_address.c
tools/testing/selftests/exec/recursion-depth.c
tools/testing/selftests/mm/gup_test.c
tools/testing/selftests/mm/protection_keys.c
tools/testing/selftests/mm/soft-dirty.c
tools/testing/selftests/mm/split_huge_page_test.c
tools/testing/selftests/mm/uffd-common.c
tools/testing/selftests/mm/uffd-common.h
tools/testing/selftests/mm/uffd-unit-tests.c

index 2216b5d5c84e44ccb1ea8d99ec7e4ba4fa059f08..dcc7af7ad4c73eb9baf785fb74226d4bb52f5c2c 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -340,7 +340,8 @@ Lee Jones <lee@kernel.org> <joneslee@google.com>
 Lee Jones <lee@kernel.org> <lee.jones@canonical.com>
 Lee Jones <lee@kernel.org> <lee.jones@linaro.org>
 Lee Jones <lee@kernel.org> <lee@ubuntu.com>
-Leonard Crestez <leonard.crestez@nxp.com> Leonard Crestez <cdleonard@gmail.com>
+Leonard Crestez <cdleonard@gmail.com> <leonard.crestez@nxp.com>
+Leonard Crestez <cdleonard@gmail.com> <leonard.crestez@intel.com>
 Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
 Leonard Göhrs <l.goehrs@pengutronix.de>
 Leonid I Ananiev <leonid.i.ananiev@intel.com>
index aa3b947fb0801dc9de9365c1d61ca4a0733431d2..079a86e680bc2d9d74c8d3b9031841d9a20760a1 100644 (file)
@@ -6173,7 +6173,6 @@ F:        include/uapi/linux/dm-*.h
 
 DEVICE-MAPPER VDO TARGET
 M:     Matthew Sakai <msakai@redhat.com>
-M:     dm-devel@lists.linux.dev
 L:     dm-devel@lists.linux.dev
 S:     Maintained
 F:     Documentation/admin-guide/device-mapper/vdo*.rst
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
new file mode 100644 (file)
index 0000000..2189e50
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <asm/system_info.h>
+#include <uapi/asm/mman.h>
+
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+       return cpu_architecture() >= CPU_ARCH_ARMv6;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
index 1140051a0c455d07cc2db9fccfe7b4cf10256671..1150b77fa281ce002f7b4c0f502851ce18728cc5 100644 (file)
@@ -63,6 +63,7 @@ SECTIONS
        STABS_DEBUG
        DWARF_DEBUG
        ELF_DETAILS
+       .hexagon.attributes 0 : { *(.hexagon.attributes) }
 
        DISCARDS
 }
diff --git a/arch/parisc/include/asm/mman.h b/arch/parisc/include/asm/mman.h
new file mode 100644 (file)
index 0000000..47c5a19
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <uapi/asm/mman.h>
+
+/* PARISC cannot allow mdwe as it needs writable stacks */
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+       return false;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
index 152239f95541953ee9c7afb65d10f6e16e090e72..7835b2cdff04a7176a0a516e7f8fa06ab098de30 100644 (file)
@@ -39,4 +39,6 @@ static inline unsigned long crash_low_size_default(void)
 #endif
 }
 
+#define HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
+
 #endif /* _X86_CRASH_RESERVE_H */
index 05402ef8964ed41332f121919660376dc7e43e6a..8aecbe4637f36e7b7e5518d01257f03e6d2a3d8b 100644 (file)
@@ -75,6 +75,9 @@ int mscode_note_digest_algo(void *context, size_t hdrlen,
 
        oid = look_up_OID(value, vlen);
        switch (oid) {
+       case OID_sha1:
+               ctx->digest_algo = "sha1";
+               break;
        case OID_sha256:
                ctx->digest_algo = "sha256";
                break;
index 5b08c50722d0f512f9605b5d3375b90cff119778..231ad7b3789d5e4aac7087e8ac76df6775a17af7 100644 (file)
@@ -227,6 +227,9 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
        struct pkcs7_parse_context *ctx = context;
 
        switch (ctx->last_oid) {
+       case OID_sha1:
+               ctx->sinfo->sig->hash_algo = "sha1";
+               break;
        case OID_sha256:
                ctx->sinfo->sig->hash_algo = "sha256";
                break;
@@ -278,6 +281,7 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
                ctx->sinfo->sig->pkey_algo = "rsa";
                ctx->sinfo->sig->encoding = "pkcs1";
                break;
+       case OID_id_ecdsa_with_sha1:
        case OID_id_ecdsa_with_sha224:
        case OID_id_ecdsa_with_sha256:
        case OID_id_ecdsa_with_sha384:
index e5f22691febd599d9a1eeb3310c19c762e715cd8..e314fd57e6f88acffad4d4b4d8fa0b1e68071b9b 100644 (file)
@@ -115,7 +115,8 @@ software_key_determine_akcipher(const struct public_key *pkey,
                 */
                if (!hash_algo)
                        return -EINVAL;
-               if (strcmp(hash_algo, "sha224") != 0 &&
+               if (strcmp(hash_algo, "sha1") != 0 &&
+                   strcmp(hash_algo, "sha224") != 0 &&
                    strcmp(hash_algo, "sha256") != 0 &&
                    strcmp(hash_algo, "sha384") != 0 &&
                    strcmp(hash_algo, "sha512") != 0 &&
index 398983be77e8bc4ee844f63b457188be9f71a1b5..2deff81f8af50bfed8159b72d119e95d35dbe510 100644 (file)
@@ -115,7 +115,7 @@ EXPORT_SYMBOL_GPL(decrypt_blob);
  * Sign the specified data blob using the private key specified by params->key.
  * The signature is wrapped in an encoding if params->encoding is specified
  * (eg. "pkcs1").  If the encoding needs to know the digest type, this can be
- * passed through params->hash_algo (eg. "sha512").
+ * passed through params->hash_algo (eg. "sha1").
  *
  * Returns the length of the data placed in the signature buffer or an error.
  */
index 487204d394266e74be91e1b47beb25eecfdc8f54..bb0bffa271b53c69410b80d04364f0a6cdc86368 100644 (file)
@@ -198,6 +198,10 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
        default:
                return -ENOPKG; /* Unsupported combination */
 
+       case OID_sha1WithRSAEncryption:
+               ctx->cert->sig->hash_algo = "sha1";
+               goto rsa_pkcs1;
+
        case OID_sha256WithRSAEncryption:
                ctx->cert->sig->hash_algo = "sha256";
                goto rsa_pkcs1;
@@ -214,6 +218,10 @@ int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
                ctx->cert->sig->hash_algo = "sha224";
                goto rsa_pkcs1;
 
+       case OID_id_ecdsa_with_sha1:
+               ctx->cert->sig->hash_algo = "sha1";
+               goto ecdsa;
+
        case OID_id_rsassa_pkcs1_v1_5_with_sha3_256:
                ctx->cert->sig->hash_algo = "sha3-256";
                goto rsa_pkcs1;
index 986f331a5fc2473877fb06bc2e1cdd191f391f8b..12e1c892f36661db5cb4419e53ef1151ec54f6f4 100644 (file)
@@ -653,6 +653,30 @@ static const struct akcipher_testvec rsa_tv_template[] = {
 static const struct akcipher_testvec ecdsa_nist_p192_tv_template[] = {
        {
        .key =
+       "\x04\xf7\x46\xf8\x2f\x15\xf6\x22\x8e\xd7\x57\x4f\xcc\xe7\xbb\xc1"
+       "\xd4\x09\x73\xcf\xea\xd0\x15\x07\x3d\xa5\x8a\x8a\x95\x43\xe4\x68"
+       "\xea\xc6\x25\xc1\xc1\x01\x25\x4c\x7e\xc3\x3c\xa6\x04\x0a\xe7\x08"
+       "\x98",
+       .key_len = 49,
+       .params =
+       "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+       "\xce\x3d\x03\x01\x01",
+       .param_len = 21,
+       .m =
+       "\xcd\xb9\xd2\x1c\xb7\x6f\xcd\x44\xb3\xfd\x63\xea\xa3\x66\x7f\xae"
+       "\x63\x85\xe7\x82",
+       .m_size = 20,
+       .algo = OID_id_ecdsa_with_sha1,
+       .c =
+       "\x30\x35\x02\x19\x00\xba\xe5\x93\x83\x6e\xb6\x3b\x63\xa0\x27\x91"
+       "\xc6\xf6\x7f\xc3\x09\xad\x59\xad\x88\x27\xd6\x92\x6b\x02\x18\x10"
+       "\x68\x01\x9d\xba\xce\x83\x08\xef\x95\x52\x7b\xa0\x0f\xe4\x18\x86"
+       "\x80\x6f\xa5\x79\x77\xda\xd0",
+       .c_size = 55,
+       .public_key_vec = true,
+       .siggen_sigver_test = true,
+       }, {
+       .key =
        "\x04\xb6\x4b\xb1\xd1\xac\xba\x24\x8f\x65\xb2\x60\x00\x90\xbf\xbd"
        "\x78\x05\x73\xe9\x79\x1d\x6f\x7c\x0b\xd2\xc3\x93\xa7\x28\xe1\x75"
        "\xf7\xd5\x95\x1d\x28\x10\xc0\x75\x50\x5c\x1a\x4f\x3f\x8f\xa5\xee"
@@ -756,6 +780,32 @@ static const struct akcipher_testvec ecdsa_nist_p192_tv_template[] = {
 static const struct akcipher_testvec ecdsa_nist_p256_tv_template[] = {
        {
        .key =
+       "\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41"
+       "\x22\xd6\x9a\xaa\x87\x17\xec\x4f\x63\x55\x2f\x94\xba\xdd\x83\xe9"
+       "\x34\x4b\xf3\xe9\x91\x13\x50\xb6\xcb\xca\x62\x08\xe7\x3b\x09\xdc"
+       "\xc3\x63\x4b\x2d\xb9\x73\x53\xe4\x45\xe6\x7c\xad\xe7\x6b\xb0\xe8"
+       "\xaf",
+       .key_len = 65,
+       .params =
+       "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+       "\xce\x3d\x03\x01\x07",
+       .param_len = 21,
+       .m =
+       "\xc2\x2b\x5f\x91\x78\x34\x26\x09\x42\x8d\x6f\x51\xb2\xc5\xaf\x4c"
+       "\x0b\xde\x6a\x42",
+       .m_size = 20,
+       .algo = OID_id_ecdsa_with_sha1,
+       .c =
+       "\x30\x46\x02\x21\x00\xf9\x25\xce\x9f\x3a\xa6\x35\x81\xcf\xd4\xe7"
+       "\xb7\xf0\x82\x56\x41\xf7\xd4\xad\x8d\x94\x5a\x69\x89\xee\xca\x6a"
+       "\x52\x0e\x48\x4d\xcc\x02\x21\x00\xd7\xe4\xef\x52\x66\xd3\x5b\x9d"
+       "\x8a\xfa\x54\x93\x29\xa7\x70\x86\xf1\x03\x03\xf3\x3b\xe2\x73\xf7"
+       "\xfb\x9d\x8b\xde\xd4\x8d\x6f\xad",
+       .c_size = 72,
+       .public_key_vec = true,
+       .siggen_sigver_test = true,
+       }, {
+       .key =
        "\x04\x8b\x6d\xc0\x33\x8e\x2d\x8b\x67\xf5\xeb\xc4\x7f\xa0\xf5\xd9"
        "\x7b\x03\xa5\x78\x9a\xb5\xea\x14\xe4\x23\xd0\xaf\xd7\x0e\x2e\xa0"
        "\xc9\x8b\xdb\x95\xf8\xb3\xaf\xac\x00\x2c\x2c\x1f\x7a\xfd\x95\x88"
@@ -866,6 +916,36 @@ static const struct akcipher_testvec ecdsa_nist_p256_tv_template[] = {
 
 static const struct akcipher_testvec ecdsa_nist_p384_tv_template[] = {
        {
+       .key = /* secp384r1(sha1) */
+       "\x04\x89\x25\xf3\x97\x88\xcb\xb0\x78\xc5\x72\x9a\x14\x6e\x7a\xb1"
+       "\x5a\xa5\x24\xf1\x95\x06\x9e\x28\xfb\xc4\xb9\xbe\x5a\x0d\xd9\x9f"
+       "\xf3\xd1\x4d\x2d\x07\x99\xbd\xda\xa7\x66\xec\xbb\xea\xba\x79\x42"
+       "\xc9\x34\x89\x6a\xe7\x0b\xc3\xf2\xfe\x32\x30\xbe\xba\xf9\xdf\x7e"
+       "\x4b\x6a\x07\x8e\x26\x66\x3f\x1d\xec\xa2\x57\x91\x51\xdd\x17\x0e"
+       "\x0b\x25\xd6\x80\x5c\x3b\xe6\x1a\x98\x48\x91\x45\x7a\x73\xb0\xc3"
+       "\xf1",
+       .key_len = 97,
+       .params =
+       "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+       "\x00\x22",
+       .param_len = 18,
+       .m =
+       "\x12\x55\x28\xf0\x77\xd5\xb6\x21\x71\x32\x48\xcd\x28\xa8\x25\x22"
+       "\x3a\x69\xc1\x93",
+       .m_size = 20,
+       .algo = OID_id_ecdsa_with_sha1,
+       .c =
+       "\x30\x66\x02\x31\x00\xf5\x0f\x24\x4c\x07\x93\x6f\x21\x57\x55\x07"
+       "\x20\x43\x30\xde\xa0\x8d\x26\x8e\xae\x63\x3f\xbc\x20\x3a\xc6\xf1"
+       "\x32\x3c\xce\x70\x2b\x78\xf1\x4c\x26\xe6\x5b\x86\xcf\xec\x7c\x7e"
+       "\xd0\x87\xd7\xd7\x6e\x02\x31\x00\xcd\xbb\x7e\x81\x5d\x8f\x63\xc0"
+       "\x5f\x63\xb1\xbe\x5e\x4c\x0e\xa1\xdf\x28\x8c\x1b\xfa\xf9\x95\x88"
+       "\x74\xa0\x0f\xbf\xaf\xc3\x36\x76\x4a\xa1\x59\xf1\x1c\xa4\x58\x26"
+       "\x79\x12\x2a\xb7\xc5\x15\x92\xc5",
+       .c_size = 104,
+       .public_key_vec = true,
+       .siggen_sigver_test = true,
+       }, {
        .key = /* secp384r1(sha224) */
        "\x04\x69\x6c\xcf\x62\xee\xd0\x0d\xe5\xb5\x2f\x70\x54\xcf\x26\xa0"
        "\xd9\x98\x8d\x92\x2a\xab\x9b\x11\xcb\x48\x18\xa1\xa9\x0d\xd5\x18"
index 1cd304de53881562cdbf7b116a0e54c9c66082a0..b2191ade9011c683145b115158a1fe1a3694d1a4 100644 (file)
@@ -806,6 +806,8 @@ static int save_iaa_wq(struct idxd_wq *wq)
                return -EINVAL;
 
        cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
+       if (!cpus_per_iaa)
+               cpus_per_iaa = 1;
 out:
        return 0;
 }
@@ -821,10 +823,12 @@ static void remove_iaa_wq(struct idxd_wq *wq)
                }
        }
 
-       if (nr_iaa)
+       if (nr_iaa) {
                cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
-       else
-               cpus_per_iaa = 0;
+               if (!cpus_per_iaa)
+                       cpus_per_iaa = 1;
+       } else
+               cpus_per_iaa = 1;
 }
 
 static int wq_table_add_wqs(int iaa, int cpu)
index d79a96679a26c92fe04c909e215b34f41128de74..d6596583ed4e780d36f9631f0039445673e629b6 100644 (file)
@@ -284,9 +284,9 @@ static int img_pwm_probe(struct platform_device *pdev)
                return PTR_ERR(imgchip->sys_clk);
        }
 
-       imgchip->pwm_clk = devm_clk_get(&pdev->dev, "imgchip");
+       imgchip->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
        if (IS_ERR(imgchip->pwm_clk)) {
-               dev_err(&pdev->dev, "failed to get imgchip clock\n");
+               dev_err(&pdev->dev, "failed to get pwm clock\n");
                return PTR_ERR(imgchip->pwm_clk);
        }
 
index bb77de6fa067efe26280b24b0f62b54ba75bcbca..009158fef2a8f1ed82fb3fb7a4c4a9b5764e723b 100644 (file)
@@ -792,7 +792,7 @@ static int uio_mmap_dma_coherent(struct vm_area_struct *vma)
         */
        vma->vm_pgoff = 0;
 
-       addr = (void *)mem->addr;
+       addr = (void *)(uintptr_t)mem->addr;
        ret = dma_mmap_coherent(mem->dma_device,
                                vma,
                                addr,
index d5f9384df1255f241d27c80ae4cd40be8d1d2609..13cc35ab5d29a7ddc079883b8a853387fcdad63e 100644 (file)
@@ -60,7 +60,7 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode)
 
                addr = dma_alloc_coherent(&priv->pdev->dev, uiomem->size,
                                          &uiomem->dma_addr, GFP_KERNEL);
-               uiomem->addr = addr ? (phys_addr_t) addr : DMEM_MAP_ERROR;
+               uiomem->addr = addr ? (uintptr_t) addr : DMEM_MAP_ERROR;
                ++uiomem;
        }
        priv->refcnt++;
@@ -89,7 +89,7 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode)
                        break;
                if (uiomem->addr) {
                        dma_free_coherent(uiomem->dma_device, uiomem->size,
-                                         (void *) uiomem->addr,
+                                         (void *) (uintptr_t) uiomem->addr,
                                          uiomem->dma_addr);
                }
                uiomem->addr = DMEM_MAP_ERROR;
index 72b33f7d4c40fcc44bce35962a9b1ec6c2fc7701..f67881cba645ba3d68b8d1023e8008c1920a1e50 100644 (file)
@@ -191,7 +191,7 @@ static int pruss_probe(struct platform_device *pdev)
                p->mem[1].size = sram_pool_sz;
                p->mem[1].memtype = UIO_MEM_PHYS;
 
-               p->mem[2].addr = (phys_addr_t) gdev->ddr_vaddr;
+               p->mem[2].addr = (uintptr_t) gdev->ddr_vaddr;
                p->mem[2].dma_addr = gdev->ddr_paddr;
                p->mem[2].size = extram_pool_sz;
                p->mem[2].memtype = UIO_MEM_DMA_COHERENT;
index 1920ed69279b5805f21ba66772dd661b6e3042e8..3314249e867474ff81075b4e007030caaf0fcd2e 100644 (file)
@@ -1359,7 +1359,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
        SET_UID(psinfo->pr_uid, from_kuid_munged(cred->user_ns, cred->uid));
        SET_GID(psinfo->pr_gid, from_kgid_munged(cred->user_ns, cred->gid));
        rcu_read_unlock();
-       strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
+       get_task_comm(psinfo->pr_fname, p);
 
        return 0;
 }
index 5f7587ca1ca7720d26a7cd192fdcd7ccd97c55bd..1e09aeea69c22e011b5a8f305421b342d04aa8b4 100644 (file)
@@ -1559,7 +1559,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
                 * needing to allocate extents from the block group.
                 */
                used = btrfs_space_info_used(space_info, true);
-               if (space_info->total_bytes - block_group->length < used) {
+               if (space_info->total_bytes - block_group->length < used &&
+                   block_group->zone_unusable < block_group->length) {
                        /*
                         * Add a reference for the list, compensate for the ref
                         * drop under the "next" label for the
index 7441245b1ceb1508558782a88759fd34ddb84818..61594eaf1f8969fc3ba04604e3470a8932450767 100644 (file)
@@ -4333,6 +4333,19 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
        if (test_and_set_bit(EXTENT_BUFFER_READING, &eb->bflags))
                goto done;
 
+       /*
+        * Between the initial test_bit(EXTENT_BUFFER_UPTODATE) and the above
+        * test_and_set_bit(EXTENT_BUFFER_READING), someone else could have
+        * started and finished reading the same eb.  In this case, UPTODATE
+        * will now be set, and we shouldn't read it in again.
+        */
+       if (unlikely(test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))) {
+               clear_bit(EXTENT_BUFFER_READING, &eb->bflags);
+               smp_mb__after_atomic();
+               wake_up_bit(&eb->bflags, EXTENT_BUFFER_READING);
+               return 0;
+       }
+
        clear_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
        eb->read_mirror = 0;
        check_buffer_tree_ref(eb);
index 347ca13d15a97586b36669e823e2ed3bec86449f..445f7716f1e2f70b3f780e7c1f03d020f0eb6346 100644 (file)
@@ -309,7 +309,7 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen)
                btrfs_warn(fs_info,
 "no extent map found for inode %llu (root %lld) when unpinning extent range [%llu, %llu), generation %llu",
                           btrfs_ino(inode), btrfs_root_id(inode->root),
-                          start, len, gen);
+                          start, start + len, gen);
                ret = -ENOENT;
                goto out;
        }
@@ -318,7 +318,7 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen)
                btrfs_warn(fs_info,
 "found extent map for inode %llu (root %lld) with unexpected start offset %llu when unpinning extent range [%llu, %llu), generation %llu",
                           btrfs_ino(inode), btrfs_root_id(inode->root),
-                          em->start, start, len, gen);
+                          em->start, start, start + len, gen);
                ret = -EUCLEAN;
                goto out;
        }
@@ -340,9 +340,9 @@ int unpin_extent_cache(struct btrfs_inode *inode, u64 start, u64 len, u64 gen)
                em->mod_len = em->len;
        }
 
-       free_extent_map(em);
 out:
        write_unlock(&tree->lock);
+       free_extent_map(em);
        return ret;
 
 }
@@ -629,13 +629,13 @@ int btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info,
                         */
                        ret = merge_extent_mapping(em_tree, existing,
                                                   em, start);
-                       if (ret) {
+                       if (WARN_ON(ret)) {
                                free_extent_map(em);
                                *em_in = NULL;
-                               WARN_ONCE(ret,
-"extent map merge error existing [%llu, %llu) with em [%llu, %llu) start %llu\n",
-                                         existing->start, existing->len,
-                                         orig_start, orig_len, start);
+                               btrfs_warn(fs_info,
+"extent map merge error existing [%llu, %llu) with em [%llu, %llu) start %llu",
+                                          existing->start, extent_map_end(existing),
+                                          orig_start, orig_start + orig_len, start);
                        }
                        free_extent_map(existing);
                }
index c4bd0e60db59253f280236740d23ed1c5b7b92f7..fa25004ab04e7b28d73dee024303c0dab4077db6 100644 (file)
@@ -2812,7 +2812,17 @@ static noinline_for_stack int scrub_supers(struct scrub_ctx *sctx,
                gen = btrfs_get_last_trans_committed(fs_info);
 
        for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
-               bytenr = btrfs_sb_offset(i);
+               ret = btrfs_sb_log_location(scrub_dev, i, 0, &bytenr);
+               if (ret == -ENOENT)
+                       break;
+
+               if (ret) {
+                       spin_lock(&sctx->stat_lock);
+                       sctx->stat.super_errors++;
+                       spin_unlock(&sctx->stat_lock);
+                       continue;
+               }
+
                if (bytenr + BTRFS_SUPER_INFO_SIZE >
                    scrub_dev->commit_total_bytes)
                        break;
index 1dc1f1946ae0eb3158a38b2d214746e7cc4a09ee..f15591f3e54fa4cd7e92103e17b0ae74eb1a54f9 100644 (file)
@@ -692,6 +692,16 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
        device->bdev = file_bdev(bdev_file);
        clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
 
+       if (device->devt != device->bdev->bd_dev) {
+               btrfs_warn(NULL,
+                          "device %s maj:min changed from %d:%d to %d:%d",
+                          device->name->str, MAJOR(device->devt),
+                          MINOR(device->devt), MAJOR(device->bdev->bd_dev),
+                          MINOR(device->bdev->bd_dev));
+
+               device->devt = device->bdev->bd_dev;
+       }
+
        fs_devices->open_devices++;
        if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
            device->devid != BTRFS_DEV_REPLACE_DEVID) {
@@ -1174,23 +1184,30 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
        struct btrfs_device *device;
        struct btrfs_device *latest_dev = NULL;
        struct btrfs_device *tmp_device;
+       int ret = 0;
 
        list_for_each_entry_safe(device, tmp_device, &fs_devices->devices,
                                 dev_list) {
-               int ret;
+               int ret2;
 
-               ret = btrfs_open_one_device(fs_devices, device, flags, holder);
-               if (ret == 0 &&
+               ret2 = btrfs_open_one_device(fs_devices, device, flags, holder);
+               if (ret2 == 0 &&
                    (!latest_dev || device->generation > latest_dev->generation)) {
                        latest_dev = device;
-               } else if (ret == -ENODATA) {
+               } else if (ret2 == -ENODATA) {
                        fs_devices->num_devices--;
                        list_del(&device->dev_list);
                        btrfs_free_device(device);
                }
+               if (ret == 0 && ret2 != 0)
+                       ret = ret2;
        }
-       if (fs_devices->open_devices == 0)
+
+       if (fs_devices->open_devices == 0) {
+               if (ret)
+                       return ret;
                return -EINVAL;
+       }
 
        fs_devices->opened = 1;
        fs_devices->latest_dev = latest_dev;
index 5a3d5ec75c5a94262c2431fce61c84d1e95f7512..4cba80b34387c102a15299a69f1bd11fc0caff2f 100644 (file)
@@ -1574,11 +1574,7 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new)
        if (!map)
                return -EINVAL;
 
-       cache->physical_map = btrfs_clone_chunk_map(map, GFP_NOFS);
-       if (!cache->physical_map) {
-               ret = -ENOMEM;
-               goto out;
-       }
+       cache->physical_map = map;
 
        zone_info = kcalloc(map->num_stripes, sizeof(*zone_info), GFP_NOFS);
        if (!zone_info) {
@@ -1690,7 +1686,6 @@ out:
        }
        bitmap_free(active);
        kfree(zone_info);
-       btrfs_free_chunk_map(map);
 
        return ret;
 }
@@ -2175,6 +2170,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
        struct btrfs_chunk_map *map;
        const bool is_metadata = (block_group->flags &
                        (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM));
+       struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
        int ret = 0;
        int i;
 
@@ -2250,6 +2246,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
        btrfs_clear_data_reloc_bg(block_group);
        spin_unlock(&block_group->lock);
 
+       down_read(&dev_replace->rwsem);
        map = block_group->physical_map;
        for (i = 0; i < map->num_stripes; i++) {
                struct btrfs_device *device = map->stripes[i].dev;
@@ -2266,13 +2263,16 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
                                       zinfo->zone_size >> SECTOR_SHIFT);
                memalloc_nofs_restore(nofs_flags);
 
-               if (ret)
+               if (ret) {
+                       up_read(&dev_replace->rwsem);
                        return ret;
+               }
 
                if (!(block_group->flags & BTRFS_BLOCK_GROUP_DATA))
                        zinfo->reserved_active_zones++;
                btrfs_dev_clear_active_zone(device, physical);
        }
+       up_read(&dev_replace->rwsem);
 
        if (!fully_written)
                btrfs_dec_block_group_ro(block_group);
index ff6f26671cfc0207961267ee1b95155d0733e835..cf1df7f16e55cc7516236c724bd64f10affe9407 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -895,6 +895,7 @@ int transfer_args_to_stack(struct linux_binprm *bprm,
                        goto out;
        }
 
+       bprm->exec += *sp_location - MAX_ARG_PAGES * PAGE_SIZE;
        *sp_location = sp;
 
 out:
index 789af5c8fade9d86354f86a6a7ffe696a9f5447d..aa1626955b2cf5b9bbedc0f8c118938dd97009b6 100644 (file)
@@ -1718,7 +1718,8 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
        struct buffer_head *dibh, *bh;
        struct gfs2_holder rd_gh;
        unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
-       u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
+       unsigned int bsize = 1 << bsize_shift;
+       u64 lblock = (offset + bsize - 1) >> bsize_shift;
        __u16 start_list[GFS2_MAX_META_HEIGHT];
        __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
        unsigned int start_aligned, end_aligned;
@@ -1729,7 +1730,7 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
        u64 prev_bnr = 0;
        __be64 *start, *end;
 
-       if (offset >= maxsize) {
+       if (offset + bsize - 1 >= maxsize) {
                /*
                 * The starting point lies beyond the allocated metadata;
                 * there are no blocks to deallocate.
index dc7048824be81d628ca12f0874c1a7508da0d5c1..bcb201ab7a412e02254f98e51d830cfef1c31c06 100644 (file)
@@ -162,6 +162,14 @@ calc_vm_flag_bits(unsigned long flags)
 
 unsigned long vm_commit_limit(void);
 
+#ifndef arch_memory_deny_write_exec_supported
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+       return true;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+#endif
+
 /*
  * Denies creating a writable executable mapping or gaining executable permissions.
  *
index 3921fbed0b28685cccfa0251e5b2d1cd4785324c..51421fdbb0bad449e28d27d6b6238aac4b03690e 100644 (file)
  *       build_OID_registry.pl to generate the data for look_up_OID().
  */
 enum OID {
+       OID_id_dsa_with_sha1,           /* 1.2.840.10030.4.3 */
        OID_id_dsa,                     /* 1.2.840.10040.4.1 */
        OID_id_ecPublicKey,             /* 1.2.840.10045.2.1 */
        OID_id_prime192v1,              /* 1.2.840.10045.3.1.1 */
        OID_id_prime256v1,              /* 1.2.840.10045.3.1.7 */
+       OID_id_ecdsa_with_sha1,         /* 1.2.840.10045.4.1 */
        OID_id_ecdsa_with_sha224,       /* 1.2.840.10045.4.3.1 */
        OID_id_ecdsa_with_sha256,       /* 1.2.840.10045.4.3.2 */
        OID_id_ecdsa_with_sha384,       /* 1.2.840.10045.4.3.3 */
@@ -28,6 +30,7 @@ enum OID {
 
        /* PKCS#1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)} */
        OID_rsaEncryption,              /* 1.2.840.113549.1.1.1 */
+       OID_sha1WithRSAEncryption,      /* 1.2.840.113549.1.1.5 */
        OID_sha256WithRSAEncryption,    /* 1.2.840.113549.1.1.11 */
        OID_sha384WithRSAEncryption,    /* 1.2.840.113549.1.1.12 */
        OID_sha512WithRSAEncryption,    /* 1.2.840.113549.1.1.13 */
@@ -64,6 +67,7 @@ enum OID {
        OID_PKU2U,                      /* 1.3.5.1.5.2.7 */
        OID_Scram,                      /* 1.3.6.1.5.5.14 */
        OID_certAuthInfoAccess,         /* 1.3.6.1.5.5.7.1.1 */
+       OID_sha1,                       /* 1.3.14.3.2.26 */
        OID_id_ansip384r1,              /* 1.3.132.0.34 */
        OID_sha256,                     /* 2.16.840.1.101.3.4.2.1 */
        OID_sha384,                     /* 2.16.840.1.101.3.4.2.2 */
index fcc06c300a72c3797751279dbeaec17b1e3f65aa..5d3a0cccc6bf8dbe0a1fcd294cf3f39d9955259c 100644 (file)
@@ -11,8 +11,8 @@
 
 #include <linux/types.h>
 
-/* 15 pointers + header align the folio_batch structure to a power of two */
-#define PAGEVEC_SIZE   15
+/* 31 pointers + header align the folio_batch structure to a power of two */
+#define PAGEVEC_SIZE   31
 
 struct folio;
 
index da79760b8be3a67378deb49a8ae8588bc19ddce0..3127e0bf7bbd15487ea6b50bd277801f6c01ae7e 100644 (file)
@@ -682,7 +682,7 @@ static void __init populate_initrd_image(char *err)
 
        printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n",
                        err);
-       file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700);
+       file = filp_open("/initrd.image", O_WRONLY|O_CREAT|O_LARGEFILE, 0700);
        if (IS_ERR(file))
                return;
 
index bbb6c3cb00e4605eced285ccbb292dc726a74bdd..066668799f757286d46a97ae5fee451ef03f8c86 100644 (file)
@@ -366,7 +366,9 @@ static int __init reserve_crashkernel_low(unsigned long long low_size)
 
        crashk_low_res.start = low_base;
        crashk_low_res.end   = low_base + low_size - 1;
+#ifdef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
        insert_resource(&iomem_resource, &crashk_low_res);
+#endif
 #endif
        return 0;
 }
@@ -448,8 +450,12 @@ retry:
 
        crashk_res.start = crash_base;
        crashk_res.end = crash_base + crash_size - 1;
+#ifdef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
+       insert_resource(&iomem_resource, &crashk_res);
+#endif
 }
 
+#ifndef HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
 static __init int insert_crashkernel_resources(void)
 {
        if (crashk_res.start < crashk_res.end)
@@ -462,3 +468,4 @@ static __init int insert_crashkernel_resources(void)
 }
 early_initcall(insert_crashkernel_resources);
 #endif
+#endif
index c3ced519e14ba44b15df3d9a42ecb0102b8e3cf6..f3e0329337f61ccfbba7e7e44ddcb89678e3796c 100644 (file)
@@ -236,6 +236,10 @@ choice
          possible to load a signed module containing the algorithm to check
          the signature on that module.
 
+config MODULE_SIG_SHA1
+       bool "Sign modules with SHA-1"
+       select CRYPTO_SHA1
+
 config MODULE_SIG_SHA256
        bool "Sign modules with SHA-256"
        select CRYPTO_SHA256
@@ -265,6 +269,7 @@ endchoice
 config MODULE_SIG_HASH
        string
        depends on MODULE_SIG || IMA_APPRAISE_MODSIG
+       default "sha1" if MODULE_SIG_SHA1
        default "sha256" if MODULE_SIG_SHA256
        default "sha384" if MODULE_SIG_SHA384
        default "sha512" if MODULE_SIG_SHA512
index ca5146006b94c6742ac770323aaf123688d65572..adf99c05adcafc494a003294e0de525005271df6 100644 (file)
@@ -2009,6 +2009,12 @@ static int console_trylock_spinning(void)
         */
        mutex_acquire(&console_lock_dep_map, 0, 1, _THIS_IP_);
 
+       /*
+        * Update @console_may_schedule for trylock because the previous
+        * owner may have been schedulable.
+        */
+       console_may_schedule = 0;
+
        return 1;
 }
 
index f8e543f1e38a06dc3a4aa2f777c7e88d444e5565..8bb106a56b3a5f7b519598343bc0fd48e81cfbb7 100644 (file)
@@ -2408,8 +2408,11 @@ static inline int prctl_set_mdwe(unsigned long bits, unsigned long arg3,
        if (bits & PR_MDWE_NO_INHERIT && !(bits & PR_MDWE_REFUSE_EXEC_GAIN))
                return -EINVAL;
 
-       /* PARISC cannot allow mdwe as it needs writable stacks */
-       if (IS_ENABLED(CONFIG_PARISC))
+       /*
+        * EOPNOTSUPP might be more appropriate here in principle, but
+        * existing userspace depends on EINVAL specifically.
+        */
+       if (!arch_memory_deny_write_exec_supported())
                return -EINVAL;
 
        current_bits = get_current_mdwe();
index 9de66bbbb3d1555603ad169fad883af1c55b9d85..4782edcbe7b9b445e932897ce97d799d73762154 100644 (file)
@@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
                goto out;
        }
        pccontext->clk = clk;
-       fp->private_data = pccontext;
-       if (clk->ops.open)
+       if (clk->ops.open) {
                err = clk->ops.open(pccontext, fp->f_mode);
-       else
-               err = 0;
-
-       if (!err) {
-               get_device(clk->dev);
+               if (err) {
+                       kfree(pccontext);
+                       goto out;
+               }
        }
+
+       fp->private_data = pccontext;
+       get_device(clk->dev);
+       err = 0;
 out:
        up_read(&clk->rwsem);
        return err;
index 217169de0920ed93778ea93e7995a0863c097ef7..dfe3ee6035ecc74da70ebd8104d23f1ef2a25cde 100644 (file)
@@ -839,7 +839,7 @@ out:
 void store_trace_entry_data(void *edata, struct trace_probe *tp, struct pt_regs *regs)
 {
        struct probe_entry_arg *earg = tp->entry_arg;
-       unsigned long val;
+       unsigned long val = 0;
        int i;
 
        if (!earg)
index 7437b2bd75c1ab48b093d390017e809af963f1e2..30de18c4fd28a907184695e3cf0f60079e956d89 100644 (file)
@@ -4197,7 +4197,23 @@ static void filemap_cachestat(struct address_space *mapping,
                                /* shmem file - in swap cache */
                                swp_entry_t swp = radix_to_swp_entry(folio);
 
+                               /* swapin error results in poisoned entry */
+                               if (non_swap_entry(swp))
+                                       goto resched;
+
+                               /*
+                                * Getting a swap entry from the shmem
+                                * inode means we beat
+                                * shmem_unuse(). rcu_read_lock()
+                                * ensures swapoff waits for us before
+                                * freeing the swapper space. However,
+                                * we can race with swapping and
+                                * invalidation, so there might not be
+                                * a shadow in the swapcache (yet).
+                                */
                                shadow = get_shadow_from_swap_cache(swp);
+                               if (!shadow)
+                                       goto resched;
                        }
 #endif
                        if (workingset_test_recent(shadow, true, &workingset))
index f2bc6dd15eb830b9c8a0b6602746e2947a6997e6..904f70b994985a7682b59a917522f284fd786950 100644 (file)
@@ -1536,7 +1536,9 @@ static inline int zap_present_ptes(struct mmu_gather *tlb,
                ptep_get_and_clear_full(mm, addr, pte, tlb->fullmm);
                arch_check_zapped_pte(vma, ptent);
                tlb_remove_tlb_entry(tlb, pte, addr);
-               VM_WARN_ON_ONCE(userfaultfd_wp(vma));
+               if (userfaultfd_pte_wp(vma, ptent))
+                       zap_install_uffd_wp_if_needed(vma, addr, pte, 1,
+                                                     details, ptent);
                ksm_might_unmap_zero_page(mm, ptent);
                return 1;
        }
index e7139952ffd9dee593fd51fa88a9c69d8d830cd3..d17d1351ec84af6ae4f49dc34d4c27c56bf77468 100644 (file)
@@ -54,6 +54,22 @@ static depot_stack_handle_t early_handle;
 
 static void init_early_allocated_pages(void);
 
+static inline void set_current_in_page_owner(void)
+{
+       /*
+        * Avoid recursion.
+        *
+        * We might need to allocate more memory from page_owner code, so make
+        * sure to signal it in order to avoid recursion.
+        */
+       current->in_page_owner = 1;
+}
+
+static inline void unset_current_in_page_owner(void)
+{
+       current->in_page_owner = 0;
+}
+
 static int __init early_page_owner_param(char *buf)
 {
        int ret = kstrtobool(buf, &page_owner_enabled);
@@ -133,23 +149,16 @@ static noinline depot_stack_handle_t save_stack(gfp_t flags)
        depot_stack_handle_t handle;
        unsigned int nr_entries;
 
-       /*
-        * Avoid recursion.
-        *
-        * Sometimes page metadata allocation tracking requires more
-        * memory to be allocated:
-        * - when new stack trace is saved to stack depot
-        */
        if (current->in_page_owner)
                return dummy_handle;
-       current->in_page_owner = 1;
 
+       set_current_in_page_owner();
        nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 2);
        handle = stack_depot_save(entries, nr_entries, flags);
        if (!handle)
                handle = failure_handle;
+       unset_current_in_page_owner();
 
-       current->in_page_owner = 0;
        return handle;
 }
 
@@ -164,9 +173,13 @@ static void add_stack_record_to_list(struct stack_record *stack_record,
        gfp_mask &= (GFP_ATOMIC | GFP_KERNEL);
        gfp_mask |= __GFP_NOWARN;
 
+       set_current_in_page_owner();
        stack = kmalloc(sizeof(*stack), gfp_mask);
-       if (!stack)
+       if (!stack) {
+               unset_current_in_page_owner();
                return;
+       }
+       unset_current_in_page_owner();
 
        stack->stack_record = stack_record;
        stack->next = NULL;
index 062d1c1097ae35fdb9fc87faa722bb403c1804fd..ce514e700d2f65f4b23ae9d579b78790505cc540 100644 (file)
@@ -116,7 +116,7 @@ static int shmem_free_file_info(struct super_block *sb, int type)
 static int shmem_get_next_id(struct super_block *sb, struct kqid *qid)
 {
        struct mem_dqinfo *info = sb_dqinfo(sb, qid->type);
-       struct rb_node *node = ((struct rb_root *)info->dqi_priv)->rb_node;
+       struct rb_node *node;
        qid_t id = from_kqid(&init_user_ns, *qid);
        struct quota_info *dqopt = sb_dqopt(sb);
        struct quota_id *entry = NULL;
@@ -126,6 +126,7 @@ static int shmem_get_next_id(struct super_block *sb, struct kqid *qid)
                return -ESRCH;
 
        down_read(&dqopt->dqio_sem);
+       node = ((struct rb_root *)info->dqi_priv)->rb_node;
        while (node) {
                entry = rb_entry(node, struct quota_id, node);
 
@@ -165,7 +166,7 @@ out_unlock:
 static int shmem_acquire_dquot(struct dquot *dquot)
 {
        struct mem_dqinfo *info = sb_dqinfo(dquot->dq_sb, dquot->dq_id.type);
-       struct rb_node **n = &((struct rb_root *)info->dqi_priv)->rb_node;
+       struct rb_node **n;
        struct shmem_sb_info *sbinfo = dquot->dq_sb->s_fs_info;
        struct rb_node *parent = NULL, *new_node = NULL;
        struct quota_id *new_entry, *entry;
@@ -176,6 +177,8 @@ static int shmem_acquire_dquot(struct dquot *dquot)
        mutex_lock(&dquot->dq_lock);
 
        down_write(&dqopt->dqio_sem);
+       n = &((struct rb_root *)info->dqi_priv)->rb_node;
+
        while (*n) {
                parent = *n;
                entry = rb_entry(parent, struct quota_id, node);
@@ -264,7 +267,7 @@ static bool shmem_is_empty_dquot(struct dquot *dquot)
 static int shmem_release_dquot(struct dquot *dquot)
 {
        struct mem_dqinfo *info = sb_dqinfo(dquot->dq_sb, dquot->dq_id.type);
-       struct rb_node *node = ((struct rb_root *)info->dqi_priv)->rb_node;
+       struct rb_node *node;
        qid_t id = from_kqid(&init_user_ns, dquot->dq_id);
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
        struct quota_id *entry = NULL;
@@ -275,6 +278,7 @@ static int shmem_release_dquot(struct dquot *dquot)
                goto out_dqlock;
 
        down_write(&dqopt->dqio_sem);
+       node = ((struct rb_root *)info->dqi_priv)->rb_node;
        while (node) {
                entry = rb_entry(node, struct quota_id, node);
 
index 712160cd41ecac1a875ad4afb5b565dddc4bc2f2..3c3539c573e7fec47b2ac883e18d7644d40197c3 100644 (file)
@@ -1444,7 +1444,8 @@ static int uffd_move_lock(struct mm_struct *mm,
                 */
                down_read(&(*dst_vmap)->vm_lock->lock);
                if (*dst_vmap != *src_vmap)
-                       down_read(&(*src_vmap)->vm_lock->lock);
+                       down_read_nested(&(*src_vmap)->vm_lock->lock,
+                                        SINGLE_DEPTH_NESTING);
        }
        mmap_read_unlock(mm);
        return err;
index 9dec853647c8e4c6fc1d0a4b0de0849ea3102a47..caed028945b046cf4caa4c842abfc900ef0a45fb 100644 (file)
@@ -1080,7 +1080,17 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page)
        mutex_lock(&acomp_ctx->mutex);
 
        src = zpool_map_handle(zpool, entry->handle, ZPOOL_MM_RO);
-       if (acomp_ctx->is_sleepable && !zpool_can_sleep_mapped(zpool)) {
+       /*
+        * If zpool_map_handle is atomic, we cannot reliably utilize its mapped buffer
+        * to do crypto_acomp_decompress() which might sleep. In such cases, we must
+        * resort to copying the buffer to a temporary one.
+        * Meanwhile, zpool_map_handle() might return a non-linearly mapped buffer,
+        * such as a kmap address of high memory or even ever a vmap address.
+        * However, sg_init_one is only equipped to handle linearly mapped low memory.
+        * In such cases, we also must copy the buffer to a temporary and lowmem one.
+        */
+       if ((acomp_ctx->is_sleepable && !zpool_can_sleep_mapped(zpool)) ||
+           !virt_addr_valid(src)) {
                memcpy(acomp_ctx->buffer, src, entry->length);
                src = acomp_ctx->buffer;
                zpool_unmap_handle(zpool, entry->handle);
@@ -1094,7 +1104,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page)
        BUG_ON(acomp_ctx->req->dlen != PAGE_SIZE);
        mutex_unlock(&acomp_ctx->mutex);
 
-       if (!acomp_ctx->is_sleepable || zpool_can_sleep_mapped(zpool))
+       if (src != acomp_ctx->buffer)
                zpool_unmap_handle(zpool, entry->handle);
 }
 
@@ -1313,6 +1323,14 @@ static unsigned long zswap_shrinker_count(struct shrinker *shrinker,
        if (!zswap_shrinker_enabled || !mem_cgroup_zswap_writeback_enabled(memcg))
                return 0;
 
+       /*
+        * The shrinker resumes swap writeback, which will enter block
+        * and may enter fs. XXX: Harmonize with vmscan.c __GFP_FS
+        * rules (may_enter_fs()), which apply on a per-folio basis.
+        */
+       if (!gfp_has_io_fs(sc->gfp_mask))
+               return 0;
+
 #ifdef CONFIG_MEMCG_KMEM
        mem_cgroup_flush_stats(memcg);
        nr_backing = memcg_page_state(memcg, MEMCG_ZSWAP_B) >> PAGE_SHIFT;
@@ -1618,6 +1636,7 @@ bool zswap_load(struct folio *folio)
        swp_entry_t swp = folio->swap;
        pgoff_t offset = swp_offset(swp);
        struct page *page = &folio->page;
+       bool swapcache = folio_test_swapcache(folio);
        struct zswap_tree *tree = swap_zswap_tree(swp);
        struct zswap_entry *entry;
        u8 *dst;
@@ -1630,7 +1649,20 @@ bool zswap_load(struct folio *folio)
                spin_unlock(&tree->lock);
                return false;
        }
-       zswap_rb_erase(&tree->rbroot, entry);
+       /*
+        * When reading into the swapcache, invalidate our entry. The
+        * swapcache can be the authoritative owner of the page and
+        * its mappings, and the pressure that results from having two
+        * in-memory copies outweighs any benefits of caching the
+        * compression work.
+        *
+        * (Most swapins go through the swapcache. The notable
+        * exception is the singleton fault on SWP_SYNCHRONOUS_IO
+        * files, which reads into a private page and may free it if
+        * the fault fails. We remain the primary owner of the entry.)
+        */
+       if (swapcache)
+               zswap_rb_erase(&tree->rbroot, entry);
        spin_unlock(&tree->lock);
 
        if (entry->length)
@@ -1645,9 +1677,10 @@ bool zswap_load(struct folio *folio)
        if (entry->objcg)
                count_objcg_event(entry->objcg, ZSWPIN);
 
-       zswap_entry_free(entry);
-
-       folio_mark_dirty(folio);
+       if (swapcache) {
+               zswap_entry_free(entry);
+               folio_mark_dirty(folio);
+       }
 
        return true;
 }
index 37e9f6804832641c176afe5ef150031748a77e9a..276f5d0d53a447f6bacaf1ed22b895554e1e3e9a 100644 (file)
@@ -11,7 +11,6 @@ help:
        @echo ''
        @echo '  acpi                   - ACPI tools'
        @echo '  bpf                    - misc BPF tools'
-       @echo '  cgroup                 - cgroup tools'
        @echo '  counter                - counter tools'
        @echo '  cpupower               - a tool for all things x86 CPU power'
        @echo '  debugging              - tools for debugging'
@@ -69,7 +68,7 @@ acpi: FORCE
 cpupower: FORCE
        $(call descend,power/$@)
 
-cgroup counter firewire hv guest bootconfig spi usb virtio mm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
+counter firewire hv guest bootconfig spi usb virtio mm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE
        $(call descend,$@)
 
 bpf/%: FORCE
@@ -116,7 +115,7 @@ freefall: FORCE
 kvm_stat: FORCE
        $(call descend,kvm/$@)
 
-all: acpi cgroup counter cpupower gpio hv firewire \
+all: acpi counter cpupower gpio hv firewire \
                perf selftests bootconfig spi turbostat usb \
                virtio mm bpf x86_energy_perf_policy \
                tmon freefall iio objtool kvm_stat wmi \
@@ -128,7 +127,7 @@ acpi_install:
 cpupower_install:
        $(call descend,power/$(@:_install=),install)
 
-cgroup_install counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install mm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
+counter_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install mm_install bpf_install objtool_install wmi_install pci_install debugging_install tracing_install:
        $(call descend,$(@:_install=),install)
 
 selftests_install:
@@ -155,7 +154,7 @@ freefall_install:
 kvm_stat_install:
        $(call descend,kvm/$(@:_install=),install)
 
-install: acpi_install cgroup_install counter_install cpupower_install gpio_install \
+install: acpi_install counter_install cpupower_install gpio_install \
                hv_install firewire_install iio_install \
                perf_install selftests_install turbostat_install usb_install \
                virtio_install mm_install bpf_install x86_energy_perf_policy_install \
@@ -169,7 +168,7 @@ acpi_clean:
 cpupower_clean:
        $(call descend,power/cpupower,clean)
 
-cgroup_clean counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean mm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
+counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean mm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean:
        $(call descend,$(@:_clean=),clean)
 
 libapi_clean:
@@ -209,7 +208,7 @@ freefall_clean:
 build_clean:
        $(call descend,build,clean)
 
-clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_clean \
+clean: acpi_clean counter_clean cpupower_clean hv_clean firewire_clean \
                perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
                mm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
                freefall_clean build_clean libbpf_clean libsubcmd_clean \
index a0b8688b0836941e0f8895f0477ea8da78a04f51..fb4472ddffd81bda3097619ad86d50d4cef6eb9e 100644 (file)
@@ -19,8 +19,8 @@ include ../lib.mk
 
 $(OUTPUT)/subdir:
        mkdir -p $@
-$(OUTPUT)/script:
-       echo '#!/bin/sh' > $@
+$(OUTPUT)/script: Makefile
+       echo '#!/bin/bash' > $@
        echo 'exit $$*' >> $@
        chmod +x $@
 $(OUTPUT)/execveat.symlink: $(OUTPUT)/execveat
index 05f94a741c7aa05841940b030aebb93f325f8214..2c575a2c0eab4124ba5d508bd7a132d7fc39d5e9 100755 (executable)
@@ -16,6 +16,8 @@ SIZE=256
 NAME_MAX=int(subprocess.check_output(["getconf", "NAME_MAX", "."]))
 
 test_num=0
+pass_num=0
+fail_num=0
 
 code='''#!/usr/bin/perl
 print "Executed interpreter! Args:\n";
@@ -42,7 +44,7 @@ foreach my $a (@ARGV) {
 # ...
 def test(name, size, good=True, leading="", root="./", target="/perl",
                      fill="A", arg="", newline="\n", hashbang="#!"):
-    global test_num, tests, NAME_MAX
+    global test_num, pass_num, fail_num, tests, NAME_MAX
     test_num += 1
     if test_num > tests:
         raise ValueError("more binfmt_script tests than expected! (want %d, expected %d)"
@@ -80,16 +82,20 @@ def test(name, size, good=True, leading="", root="./", target="/perl",
         if good:
             print("ok %d - binfmt_script %s (successful good exec)"
                   % (test_num, name))
+            pass_num += 1
         else:
             print("not ok %d - binfmt_script %s succeeded when it should have failed"
                   % (test_num, name))
+            fail_num = 1
     else:
         if good:
             print("not ok %d - binfmt_script %s failed when it should have succeeded (rc:%d)"
                   % (test_num, name, proc.returncode))
+            fail_num = 1
         else:
             print("ok %d - binfmt_script %s (correctly failed bad exec)"
                   % (test_num, name))
+            pass_num += 1
 
     # Clean up crazy binaries
     os.unlink(script)
@@ -166,6 +172,8 @@ test(name="two-under-trunc-arg", size=int(SIZE/2), arg=" ")
 test(name="two-under-leading",   size=int(SIZE/2), leading=" ")
 test(name="two-under-lead-trunc-arg", size=int(SIZE/2), leading=" ", arg=" ")
 
+print("# Totals: pass:%d fail:%d xfail:0 xpass:0 skip:0 error:0" % (pass_num, fail_num))
+
 if test_num != tests:
     raise ValueError("fewer binfmt_script tests than expected! (ran %d, expected %d"
                      % (test_num, tests))
index 0546ca24f2b20ceb7ee9deb26b80fc637c7a2ada..6418ded40bdddc7efa95c047d848359709f1ee70 100644 (file)
@@ -98,10 +98,9 @@ static int check_execveat_invoked_rc(int fd, const char *path, int flags,
        if (child == 0) {
                /* Child: do execveat(). */
                rc = execveat_(fd, path, argv, envp, flags);
-               ksft_print_msg("execveat() failed, rc=%d errno=%d (%s)\n",
+               ksft_print_msg("child execveat() failed, rc=%d errno=%d (%s)\n",
                               rc, errno, strerror(errno));
-               ksft_test_result_fail("%s\n", test_name);
-               exit(1);  /* should not reach here */
+               exit(errno);
        }
        /* Parent: wait for & check child's exit status. */
        rc = waitpid(child, &status, 0);
@@ -226,11 +225,14 @@ static int check_execveat_pathmax(int root_dfd, const char *src, int is_script)
         * "If the command name is found, but it is not an executable utility,
         * the exit status shall be 126."), so allow either.
         */
-       if (is_script)
+       if (is_script) {
+               ksft_print_msg("Invoke script via root_dfd and relative filename\n");
                fail += check_execveat_invoked_rc(root_dfd, longpath + 1, 0,
                                                  127, 126);
-       else
+       } else {
+               ksft_print_msg("Invoke exec via root_dfd and relative filename\n");
                fail += check_execveat(root_dfd, longpath + 1, 0);
+       }
 
        return fail;
 }
index d487c2f6a61509f6c4feb7930272c33f88d80239..17e3207d34ae7e74779964a44d62c8763d44a087 100644 (file)
@@ -5,6 +5,7 @@
 #include <link.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "../kselftest.h"
 
 struct Statistics {
        unsigned long long load_address;
@@ -41,28 +42,23 @@ int main(int argc, char **argv)
        unsigned long long misalign;
        int ret;
 
+       ksft_print_header();
+       ksft_set_plan(1);
+
        ret = dl_iterate_phdr(ExtractStatistics, &extracted);
-       if (ret != 1) {
-               fprintf(stderr, "FAILED\n");
-               return 1;
-       }
+       if (ret != 1)
+               ksft_exit_fail_msg("FAILED: dl_iterate_phdr\n");
 
-       if (extracted.alignment == 0) {
-               fprintf(stderr, "No alignment found\n");
-               return 1;
-       } else if (extracted.alignment & (extracted.alignment - 1)) {
-               fprintf(stderr, "Alignment is not a power of 2\n");
-               return 1;
-       }
+       if (extracted.alignment == 0)
+               ksft_exit_fail_msg("FAILED: No alignment found\n");
+       else if (extracted.alignment & (extracted.alignment - 1))
+               ksft_exit_fail_msg("FAILED: Alignment is not a power of 2\n");
 
        misalign = extracted.load_address & (extracted.alignment - 1);
-       if (misalign) {
-               printf("alignment = %llu, load_address = %llu\n",
-                       extracted.alignment, extracted.load_address);
-               fprintf(stderr, "FAILED\n");
-               return 1;
-       }
+       if (misalign)
+               ksft_exit_fail_msg("FAILED: alignment = %llu, load_address = %llu\n",
+                                  extracted.alignment, extracted.load_address);
 
-       fprintf(stderr, "PASS\n");
-       return 0;
+       ksft_test_result_pass("Completed\n");
+       ksft_finished();
 }
index 2dbd5bc45b3ed0fb095214d395e0132ca3c76a62..b2f37d86a5f623b1a8e91af7b42bfc6db79af34b 100644 (file)
 #include <fcntl.h>
 #include <sys/mount.h>
 #include <unistd.h>
+#include "../kselftest.h"
 
 int main(void)
 {
+       int fd, rv;
+
+       ksft_print_header();
+       ksft_set_plan(1);
+
        if (unshare(CLONE_NEWNS) == -1) {
                if (errno == ENOSYS || errno == EPERM) {
-                       fprintf(stderr, "error: unshare, errno %d\n", errno);
-                       return 4;
+                       ksft_test_result_skip("error: unshare, errno %d\n", errno);
+                       ksft_finished();
                }
-               fprintf(stderr, "error: unshare, errno %d\n", errno);
-               return 1;
-       }
-       if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
-               fprintf(stderr, "error: mount '/', errno %d\n", errno);
-               return 1;
+               ksft_exit_fail_msg("error: unshare, errno %d\n", errno);
        }
+
+       if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL) == -1)
+               ksft_exit_fail_msg("error: mount '/', errno %d\n", errno);
+
        /* Require "exec" filesystem. */
-       if (mount(NULL, "/tmp", "ramfs", 0, NULL) == -1) {
-               fprintf(stderr, "error: mount ramfs, errno %d\n", errno);
-               return 1;
-       }
+       if (mount(NULL, "/tmp", "ramfs", 0, NULL) == -1)
+               ksft_exit_fail_msg("error: mount ramfs, errno %d\n", errno);
 
 #define FILENAME "/tmp/1"
 
-       int fd = creat(FILENAME, 0700);
-       if (fd == -1) {
-               fprintf(stderr, "error: creat, errno %d\n", errno);
-               return 1;
-       }
+       fd = creat(FILENAME, 0700);
+       if (fd == -1)
+               ksft_exit_fail_msg("error: creat, errno %d\n", errno);
+
 #define S "#!" FILENAME "\n"
-       if (write(fd, S, strlen(S)) != strlen(S)) {
-               fprintf(stderr, "error: write, errno %d\n", errno);
-               return 1;
-       }
+       if (write(fd, S, strlen(S)) != strlen(S))
+               ksft_exit_fail_msg("error: write, errno %d\n", errno);
+
        close(fd);
 
-       int rv = execve(FILENAME, NULL, NULL);
-       if (rv == -1 && errno == ELOOP) {
-               return 0;
-       }
-       fprintf(stderr, "error: execve, rv %d, errno %d\n", rv, errno);
-       return 1;
+       rv = execve(FILENAME, NULL, NULL);
+       ksft_test_result(rv == -1 && errno == ELOOP,
+                        "execve failed as expected (ret %d, errno %d)\n", rv, errno);
+       ksft_finished();
 }
index cbe99594d319b4156da2c48a09001d0f06e7a36f..18a49c70d4c6354baac96073bc99446ad70b0b85 100644 (file)
@@ -203,7 +203,7 @@ int main(int argc, char **argv)
        ksft_print_header();
        ksft_set_plan(nthreads);
 
-       filed = open(file, O_RDWR|O_CREAT);
+       filed = open(file, O_RDWR|O_CREAT, 0664);
        if (filed < 0)
                ksft_exit_fail_msg("Unable to open %s: %s\n", file, strerror(errno));
 
index f822ae31af22e20103900084f71e280e182a310a..374a308174d2ba7c17f496a4c94364e34815e355 100644 (file)
@@ -1745,9 +1745,12 @@ void pkey_setup_shadow(void)
        shadow_pkey_reg = __read_pkey_reg();
 }
 
+pid_t parent_pid;
+
 void restore_settings_atexit(void)
 {
-       cat_into_file(buf, "/proc/sys/vm/nr_hugepages");
+       if (parent_pid == getpid())
+               cat_into_file(buf, "/proc/sys/vm/nr_hugepages");
 }
 
 void save_settings(void)
@@ -1773,6 +1776,7 @@ void save_settings(void)
                exit(__LINE__);
        }
 
+       parent_pid = getpid();
        atexit(restore_settings_atexit);
        close(fd);
 }
index cc5f144430d4d246fa5dfd09445b6ecc78f46a81..7dbfa53d93a05f504ea4c1019bce92677cec136d 100644 (file)
@@ -137,7 +137,7 @@ static void test_mprotect(int pagemap_fd, int pagesize, bool anon)
                if (!map)
                        ksft_exit_fail_msg("anon mmap failed\n");
        } else {
-               test_fd = open(fname, O_RDWR | O_CREAT);
+               test_fd = open(fname, O_RDWR | O_CREAT, 0664);
                if (test_fd < 0) {
                        ksft_test_result_skip("Test %s open() file failed\n", __func__);
                        return;
index 856662d2f87a1b0db004c3e4297d3e5697424d62..6c988bd2f335677b9b87af1594407e63f907e542 100644 (file)
@@ -223,7 +223,7 @@ void split_file_backed_thp(void)
                ksft_exit_fail_msg("Fail to create file-backed THP split testing file\n");
        }
 
-       fd = open(testfile, O_CREAT|O_WRONLY);
+       fd = open(testfile, O_CREAT|O_WRONLY, 0664);
        if (fd == -1) {
                ksft_perror("Cannot open testing file");
                goto cleanup;
index b0ac0ec2356d6533c55662949a0cd40ebe0a9c8d..7ad6ba660c7d6f1f5762d0b231b92b05e971a3c5 100644 (file)
@@ -18,6 +18,7 @@ bool test_uffdio_wp = true;
 unsigned long long *count_verify;
 uffd_test_ops_t *uffd_test_ops;
 uffd_test_case_ops_t *uffd_test_case_ops;
+atomic_bool ready_for_fork;
 
 static int uffd_mem_fd_create(off_t mem_size, bool hugetlb)
 {
@@ -518,6 +519,8 @@ void *uffd_poll_thread(void *arg)
        pollfd[1].fd = pipefd[cpu*2];
        pollfd[1].events = POLLIN;
 
+       ready_for_fork = true;
+
        for (;;) {
                ret = poll(pollfd, 2, -1);
                if (ret <= 0) {
index cb055282c89c966e93804478a2d47513939375a8..cc5629c3d2aa1057b9718ea5cbe3ef469b222877 100644 (file)
@@ -32,6 +32,7 @@
 #include <inttypes.h>
 #include <stdint.h>
 #include <sys/random.h>
+#include <stdatomic.h>
 
 #include "../kselftest.h"
 #include "vm_util.h"
@@ -103,6 +104,7 @@ extern bool map_shared;
 extern bool test_uffdio_wp;
 extern unsigned long long *count_verify;
 extern volatile bool test_uffdio_copy_eexist;
+extern atomic_bool ready_for_fork;
 
 extern uffd_test_ops_t anon_uffd_test_ops;
 extern uffd_test_ops_t shmem_uffd_test_ops;
index 2b9f8cc52639d1942238b41a1ad55edc6bd406ed..21ec23206ab44a0ed036cec25e2c79a461c83020 100644 (file)
@@ -775,6 +775,8 @@ static void uffd_sigbus_test_common(bool wp)
        char c;
        struct uffd_args args = { 0 };
 
+       ready_for_fork = false;
+
        fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
 
        if (uffd_register(uffd, area_dst, nr_pages * page_size,
@@ -790,6 +792,9 @@ static void uffd_sigbus_test_common(bool wp)
        if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
                err("uffd_poll_thread create");
 
+       while (!ready_for_fork)
+               ; /* Wait for the poll_thread to start executing before forking */
+
        pid = fork();
        if (pid < 0)
                err("fork");
@@ -829,6 +834,8 @@ static void uffd_events_test_common(bool wp)
        char c;
        struct uffd_args args = { 0 };
 
+       ready_for_fork = false;
+
        fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
        if (uffd_register(uffd, area_dst, nr_pages * page_size,
                          true, wp, false))
@@ -838,6 +845,9 @@ static void uffd_events_test_common(bool wp)
        if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
                err("uffd_poll_thread create");
 
+       while (!ready_for_fork)
+               ; /* Wait for the poll_thread to start executing before forking */
+
        pid = fork();
        if (pid < 0)
                err("fork");
@@ -1427,7 +1437,8 @@ uffd_test_case_t uffd_tests[] = {
                .uffd_fn = uffd_sigbus_wp_test,
                .mem_targets = MEM_ALL,
                .uffd_feature_required = UFFD_FEATURE_SIGBUS |
-               UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_PAGEFAULT_FLAG_WP,
+               UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_PAGEFAULT_FLAG_WP |
+               UFFD_FEATURE_WP_HUGETLBFS_SHMEM,
        },
        {
                .name = "events",