Linux 5.15.37
Greg Kroah-Hartman
maintainerI'm announcing the release of the 5.15.37 kernel.
All users of the 5.15 kernel series must upgrade.
The updated 5.15.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.15.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Makefile | 2 arch/arm/boot/dts/socfpga.dtsi | 2 arch/arm/boot/dts/socfpga_arria10.dtsi | 2 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 2 arch/arm64/boot/dts/intel/socfpga_agilex.dtsi | 2 arch/powerpc/kernel/kvm.c | 3 arch/powerpc/kernel/signal_32.c | 4 arch/powerpc/kernel/signal_64.c | 2 arch/x86/kernel/fpu/signal.c | 7 drivers/block/Kconfig | 16 drivers/block/floppy.c | 43 drivers/gpu/drm/armada/armada_gem.c | 7 drivers/spi/spi-cadence-quadspi.c | 24 fs/btrfs/file.c | 142 ++ fs/btrfs/inode.c | 28 fs/btrfs/ioctl.c | 5 fs/erofs/data.c | 2 fs/ext4/file.c | 5 fs/f2fs/file.c | 2 fs/fuse/file.c | 2 fs/gfs2/bmap.c | 60 - fs/gfs2/file.c | 252 ++++- fs/gfs2/glock.c | 330 +++++- fs/gfs2/glock.h | 20 fs/gfs2/incore.h | 4 fs/iomap/buffered-io.c | 2 fs/iomap/direct-io.c | 29 fs/ntfs/file.c | 2 fs/ntfs3/file.c | 2 fs/xfs/xfs_file.c | 6 fs/zonefs/super.c | 4 include/linux/bpf.h | 101 +- include/linux/bpf_verifier.h | 18 include/linux/iomap.h | 11 include/linux/mm.h | 3 include/linux/pagemap.h | 58 - include/linux/uio.h | 4 kernel/bpf/btf.c | 16 kernel/bpf/cgroup.c | 2 kernel/bpf/helpers.c | 12 kernel/bpf/map_iter.c | 4 kernel/bpf/ringbuf.c | 2 kernel/bpf/syscall.c | 2 kernel/bpf/verifier.c | 488 ++++------ kernel/trace/bpf_trace.c | 22 lib/iov_iter.c | 98 +- mm/filemap.c | 4 mm/gup.c | 120 ++ mm/kfence/core.c | 11 mm/kfence/kfence.h | 3 net/core/bpf_sk_storage.c | 2 net/core/filter.c | 64 - net/core/sock_map.c | 2 tools/testing/selftests/bpf/prog_tests/ksyms_btf.c | 14 tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c | 29 tools/testing/selftests/bpf/verifier/calls.c | 19 56 files changed, 1471 insertions(+), 651 deletions(-)
Andreas Gruenbacher (14):
gup: Turn fault_in_pages_{readable,writeable} into fault_in_{readable,writeable}
iov_iter: Turn iov_iter_fault_in_readable into fault_in_iov_iter_readable
iov_iter: Introduce fault_in_iov_iter_writeable
gfs2: Add wrapper for iomap_file_buffered_write
gfs2: Clean up function may_grant
gfs2: Move the inode glock locking to gfs2_file_buffered_write
gfs2: Eliminate ip->i_gh
gfs2: Fix mmap + page fault deadlocks for buffered I/O
iomap: Fix iomap_dio_rw return value for user copies
iomap: Support partial direct I/O on user copy failures
iomap: Add done_before argument to iomap_dio_rw
gup: Introduce FOLL_NOFAULT flag to disable page faults
iov_iter: Introduce nofault flag to disable page faults
gfs2: Fix mmap + page fault deadlocks for direct I/O
Bob Peterson (1):
gfs2: Introduce flag for glock holder auto-demotion
Dinh Nguyen (2):
spi: cadence-quadspi: fix write completion support
ARM: dts: socfpga: change qspi to "intel,socfpga-qspi"
Filipe Manana (2):
btrfs: fix deadlock due to page faults during direct IO reads and writes
btrfs: fallback to blocking mode when doing async dio over multiple extents
Greg Kroah-Hartman (1):
Linux 5.15.37
Hao Luo (9):
bpf: Introduce composable reg, ret and arg types.
bpf: Replace ARG_XXX_OR_NULL with ARG_XXX | PTR_MAYBE_NULL
bpf: Replace RET_XXX_OR_NULL with RET_XXX | PTR_MAYBE_NULL
bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL
bpf: Introduce MEM_RDONLY flag
bpf: Convert PTR_TO_MEM_OR_NULL to composable types.
bpf: Make per_cpu_ptr return rdonly PTR_TO_MEM.
bpf: Add MEM_RDONLY for helper args that are pointers to rdonly mem. bpf/selftests: Test PTR_TO_RDONLY_MEM
Kumar Kartikeya Dwivedi (2):
bpf: Fix crash due to out of bounds access into reg2btf_ids. selftests/bpf: Add test for reg2btf_ids out of bounds access
Linus Torvalds (1):
mm: gup: make fault_in_safe_writeable() use fixup_user_fault()
Muchun Song (1):
mm: kfence: fix objcgs vector allocation
Willy Tarreau (1):
floppy: disable FDRAWCMD by default
Greg Kroah-Hartman
maintainerMakefile +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 15 -SUBLEVEL = 36 +SUBLEVEL = 37 EXTRAVERSION = NAME = Trick or Treat
arch/arm/boot/dts/socfpga.dtsi +1 -1
@@ -782,7 +782,7 @@ ocram: sram@ffff0000 { }; qspi: spi@ff705000 { - compatible = "cdns,qspi-nor"; + compatible = "intel,socfpga-qspi", "cdns,qspi-nor"; #address-cells = <1>; #size-cells = <0>; reg = <0xff705000 0x1000>,
arch/arm/boot/dts/socfpga_arria10.dtsi +1 -1
@@ -756,7 +756,7 @@ usb0-ecc@ff8c8800 { }; qspi: spi@ff809000 { - compatible = "cdns,qspi-nor"; + compatible = "intel,socfpga-qspi", "cdns,qspi-nor"; #address-cells = <1>; #size-cells = <0>; reg = <0xff809000 0x100>,
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +1 -1
@@ -594,7 +594,7 @@ emac0-tx-ecc@ff8c0400 { }; qspi: spi@ff8d2000 { - compatible = "cdns,qspi-nor"; + compatible = "intel,socfpga-qspi", "cdns,qspi-nor"; #address-cells = <1>; #size-cells = <0>; reg = <0xff8d2000 0x100>,
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +1 -1
@@ -628,7 +628,7 @@ sdmmca-ecc@ff8c8c00 { }; qspi: spi@ff8d2000 { - compatible = "cdns,qspi-nor"; + compatible = "intel,socfpga-qspi", "cdns,qspi-nor"; #address-cells = <1>; #size-cells = <0>; reg = <0xff8d2000 0x100>,
arch/powerpc/kernel/kvm.c +2 -1
@@ -669,7 +669,8 @@ static void __init kvm_use_magic_page(void)on_each_cpu (kvm_map_magic_page, &features,1 );/* Quick self-test to see if the mapping works */ -if (fault_in_pages_readable ((const char *)KVM_MAGIC_PAGE ,sizeof (u32))) { +if (fault_in_readable ((const char __user *)KVM_MAGIC_PAGE , +sizeof (u32))) { kvm_patching_worked = false;return ; }
arch/powerpc/kernel/signal_32.c +2 -2
@@ -1048,7 +1048,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,if (new_ctx ==NULL )return 0 ;if (!access_ok (new_ctx, ctx_size) || -fault_in_pages_readable ((u8 __user *)new_ctx, ctx_size)) +fault_in_readable ((char __user *)new_ctx, ctx_size))return -EFAULT ;/*
@@ -1239,7 +1239,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx,#endif if (!access_ok (ctx,sizeof (*ctx)) || -fault_in_pages_readable ((u8 __user *)ctx,sizeof (*ctx))) +fault_in_readable ((char __user *)ctx,sizeof (*ctx)))return -EFAULT ;/*
arch/powerpc/kernel/signal_64.c +1 -1
@@ -688,7 +688,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,if (new_ctx ==NULL )return 0 ;if (!access_ok (new_ctx, ctx_size) || -fault_in_pages_readable ((u8 __user *)new_ctx, ctx_size)) +fault_in_readable ((char __user *)new_ctx, ctx_size))return -EFAULT ;/*
arch/x86/kernel/fpu/signal.c +3 -4
@@ -205,7 +205,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)fpregs_unlock ();if (ret) { -if (!fault_in_pages_writeable (buf_fx, fpu_user_xstate_size)) +if (!fault_in_writeable (buf_fx, fpu_user_xstate_size)) goto retry;return -EFAULT ; }
@@ -278,10 +278,9 @@ static int restore_fpregs_from_user(void __user *buf, u64 xrestore,if (ret != -EFAULT )return -EINVAL ; - ret =fault_in_pages_readable (buf, size); -if (!ret) +if (!fault_in_readable (buf, size)) goto retry; -return ret; +return -EFAULT ; }/*
drivers/block/Kconfig +16 -0
@@ -33,6 +33,22 @@ config BLK_DEV_FD To compile this driver as a module, choose M here: the module will be called floppy. +config BLK_DEV_FD_RAWCMD + bool "Support for raw floppy disk commands (DEPRECATED)" + depends on BLK_DEV_FD + help + If you want to use actual physical floppies and expect to do + special low-level hardware accesses to them (access and use + non-standard formats, for example), then enable this. + + Note that the code enabled by this option is rarely used and + might be unstable or insecure, and distros should not enable it. + + Note: FDRAWCMD is deprecated and will be removed from the kernel + in the near future. + + If unsure, say N. + config AMIGA_FLOPPY tristate "Amiga floppy support" depends on AMIGA
drivers/block/floppy.c +32 -11
67 lines not on this page · raw message
drivers/gpu/drm/armada/armada_gem.c +3 -4
@@ -336,7 +336,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,struct drm_armada_gem_pwrite *args = data;struct armada_gem_object *dobj;char __user *ptr; -int ret; +int ret =0 ;DRM_DEBUG_DRIVER ("handle %u off %u size %u ptr 0x%llx\n" , args->handle, args->offset, args->size, args->ptr);
@@ -349,9 +349,8 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,if (!access_ok (ptr, args->size))return -EFAULT ; - ret =fault_in_pages_readable (ptr, args->size); -if (ret) -return ret; +if (fault_in_readable (ptr, args->size)) +return -EFAULT ; dobj =armada_gem_object_lookup (file, args->handle);if (dobj ==NULL )
drivers/spi/spi-cadence-quadspi.c +21 -3
@@ -36,6 +36,7 @@/* Quirks */ #define CQSPI_NEEDS_WR_DELAY BIT(0)#define CQSPI_DISABLE_DAC_MODE BIT(1) +#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3)/* Capabilities */ #define CQSPI_SUPPORTS_OCTAL BIT(0)
@@ -83,6 +84,7 @@ struct cqspi_st {u32 wr_delay;bool use_direct_mode;struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT ]; +bool wr_completion; };struct cqspi_driver_platdata {
@@ -797,9 +799,11 @@ static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,* polling on the controller's side. spinand and spi-nor will take * care of polling the status register. */ - reg =readl (reg_base +CQSPI_REG_WR_COMPLETION_CTRL ); - reg |=CQSPI_REG_WR_DISABLE_AUTO_POLL ; -writel (reg, reg_base +CQSPI_REG_WR_COMPLETION_CTRL ); +if (cqspi->wr_completion) { + reg =readl (reg_base +CQSPI_REG_WR_COMPLETION_CTRL ); + reg |=CQSPI_REG_WR_DISABLE_AUTO_POLL ; +writel (reg, reg_base +CQSPI_REG_WR_COMPLETION_CTRL ); + } reg =readl (reg_base +CQSPI_REG_SIZE ); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK ;
@@ -1532,6 +1536,10 @@ static int cqspi_probe(struct platform_device *pdev) cqspi->master_ref_clk_hz =clk_get_rate (cqspi->clk); master->max_speed_hz = cqspi->master_ref_clk_hz; + +/* write completion is supported by default */ + cqspi->wr_completion = true; + ddata =of_device_get_match_data (dev);if (ddata) {if (ddata->quirks &CQSPI_NEEDS_WR_DELAY )
@@ -1541,6 +1549,8 @@ static int cqspi_probe(struct platform_device *pdev) master->mode_bits |=SPI_RX_OCTAL |SPI_TX_OCTAL ;if (!(ddata->quirks &CQSPI_DISABLE_DAC_MODE )) cqspi->use_direct_mode = true; +if (ddata->quirks &CQSPI_NO_SUPPORT_WR_COMPLETION ) + cqspi->wr_completion = false; } ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
@@ -1649,6 +1659,10 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = { .quirks = CQSPI_DISABLE_DAC_MODE, }; +static const struct cqspi_driver_platdata socfpga_qspi = { + .quirks =CQSPI_NO_SUPPORT_WR_COMPLETION , +}; +static const struct of_device_id cqspi_dt_ids[] = { { .compatible ="cdns,qspi-nor" ,
@@ -1666,6 +1680,10 @@ static const struct of_device_id cqspi_dt_ids[] = { .compatible = "intel,lgm-qspi", .data = &intel_lgm_qspi, }, + { + .compatible = "intel,socfpga-qspi", + .data = (void *)&socfpga_qspi, + }, {/* end of table */ } };
fs/btrfs/file.c +125 -17
193 lines not on this page · raw message
fs/btrfs/inode.c +28 -0
@@ -7961,6 +7961,34 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, } len =min (len, em->len - (start - em->start)); + +/* +* If we have a NOWAIT request and the range contains multiple extents +* (or a mix of extents and holes), then we return -EAGAIN to make the +* caller fallback to a context where it can do a blocking (without +* NOWAIT) request. This way we avoid doing partial IO and returning +* success to the caller, which is not optimal for writes and for reads +* it can result in unexpected behaviour for an application. +* +* When doing a read, because we use IOMAP_DIO_PARTIAL when calling +* iomap_dio_rw(), we can end up returning less data then what the caller +* asked for, resulting in an unexpected, and incorrect, short read. +* That is, the caller asked to read N bytes and we return less than that, +* which is wrong unless we are crossing EOF. This happens if we get a +* page fault error when trying to fault in pages for the buffer that is +* associated to the struct iov_iter passed to iomap_dio_rw(), and we +* have previously submitted bios for other extents in the range, in +* which case iomap_dio_rw() may return us EIOCBQUEUED if not all of +* those bios have completed by the time we get the page fault error, +* which we return back to our caller - we should only return EIOCBQUEUED +* after we have submitted bios for all the extents in the range. +*/ +if ((flags &IOMAP_NOWAIT ) && len < length) { +free_extent_map (em); + ret = -EAGAIN ; + goto unlock_err; + } +if (write) { ret =btrfs_get_blocks_direct_write (&em, inode, dio_data, start, len);
fs/btrfs/ioctl.c +2 -3
@@ -2258,9 +2258,8 @@ static noinline int search_ioctl(struct inode *inode, key.offset = sk->min_offset;while (1 ) { - ret =fault_in_pages_writeable (ubuf + sk_offset, - *buf_size - sk_offset); -if (ret) + ret = -EFAULT ; +if (fault_in_writeable (ubuf + sk_offset, *buf_size - sk_offset))break ; ret =btrfs_search_forward (root, &key, path, sk->min_transid);
fs/erofs/data.c +1 -1
@@ -287,7 +287,7 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)if (!err)return iomap_dio_rw (iocb, to, &erofs_iomap_ops, -NULL ,0 ); +NULL ,0 ,0 );if (err <0 )return err; }
fs/ext4/file.c +3 -2
@@ -74,7 +74,7 @@ static ssize_t ext4_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)return generic_file_read_iter (iocb, to); } - ret =iomap_dio_rw (iocb, to, &ext4_iomap_ops,NULL ,0 ); + ret =iomap_dio_rw (iocb, to, &ext4_iomap_ops,NULL ,0 ,0 );inode_unlock_shared (inode);file_accessed (iocb->ki_filp);
@@ -566,7 +566,8 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)if (ilock_shared) iomap_ops = &ext4_iomap_overwrite_ops; ret =iomap_dio_rw (iocb, from, iomap_ops, &ext4_dio_write_ops, - (unaligned_io || extend) ?IOMAP_DIO_FORCE_WAIT :0 ); + (unaligned_io || extend) ?IOMAP_DIO_FORCE_WAIT :0 , +0 );if (ret == -ENOTBLK ) ret =0 ;
fs/f2fs/file.c +1 -1
@@ -4279,7 +4279,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)size_t target_size =0 ;int err; -if (iov_iter_fault_in_readable (from,iov_iter_count (from))) +if (fault_in_iov_iter_readable (from,iov_iter_count (from)))set_inode_flag (inode,FI_NO_PREALLOC );if ((iocb->ki_flags &IOCB_NOWAIT )) {
fs/fuse/file.c +1 -1
@@ -1164,7 +1164,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, again: err = -EFAULT ; -if (iov_iter_fault_in_readable (ii, bytes)) +if (fault_in_iov_iter_readable (ii, bytes))break ; err = -ENOMEM ;
fs/gfs2/bmap.c +1 -59
95 lines not on this page · raw message
fs/gfs2/file.c +229 -23
344 lines not on this page · raw message
fs/gfs2/glock.c +246 -84
450 lines not on this page · raw message
fs/gfs2/glock.h +20 -0
@@ -150,6 +150,8 @@ static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *list_for_each_entry (gh, &gl->gl_holders, gh_list) {if (!test_bit (HIF_HOLDER , &gh->gh_iflags))break ; +if (test_bit (HIF_MAY_DEMOTE , &gh->gh_iflags)) +continue ;if (gh->gh_owner_pid == pid) goto out; }
@@ -325,6 +327,24 @@ static inline void glock_clear_object(struct gfs2_glock *gl, void *object)spin_unlock (&gl->gl_lockref.lock); } +static inline void gfs2_holder_allow_demote (struct gfs2_holder *gh) +{ +struct gfs2_glock *gl = gh->gh_gl; + +spin_lock (&gl->gl_lockref.lock); +set_bit (HIF_MAY_DEMOTE , &gh->gh_iflags); +spin_unlock (&gl->gl_lockref.lock); +} + +static inline void gfs2_holder_disallow_demote (struct gfs2_holder *gh) +{ +struct gfs2_glock *gl = gh->gh_gl; + +spin_lock (&gl->gl_lockref.lock); +clear_bit (HIF_MAY_DEMOTE , &gh->gh_iflags); +spin_unlock (&gl->gl_lockref.lock); +} +extern void gfs2_inode_remember_delete (struct gfs2_glock *gl,u64 generation);extern bool gfs2_inode_already_deleted (struct gfs2_glock *gl,u64 generation);
fs/gfs2/incore.h +2 -2
@@ -252,6 +252,7 @@ struct gfs2_lkstats {enum {/* States */ +HIF_MAY_DEMOTE =1 ,HIF_HOLDER =6 ,/* Set for gh that "holds" the glock */ HIF_WAIT =10 , };
@@ -386,9 +387,8 @@ struct gfs2_inode {u64 i_generation;u64 i_eattr;unsigned long i_flags;/* GIF_... */ -struct gfs2_glock *i_gl;/* Move into i_gh? */ +struct gfs2_glock *i_gl;struct gfs2_holder i_iopen_gh; -struct gfs2_holder i_gh;/* for prepare/commit_write only */ struct gfs2_qadata *i_qadata;/* quota allocation data */ struct gfs2_holder i_rgd_gh;struct gfs2_blkreserv i_res;/* rgrp multi-block reservation */
fs/iomap/buffered-io.c +1 -1
@@ -757,7 +757,7 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)* same page as we're writing to, without it being marked * up-to-date. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (fault_in_iov_iter_readable (i, bytes))) { status = -EFAULT ;break ; }
fs/iomap/direct-io.c +26 -3
@@ -31,6 +31,7 @@ struct iomap_dio {atomic_t ref;unsigned flags;int error; +size_t done_before;bool wait_for_completion;union {
@@ -124,6 +125,9 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio)if (ret >0 && (dio->flags &IOMAP_DIO_NEED_SYNC )) ret =generic_write_sync (iocb, ret); +if (ret >0 ) + ret += dio->done_before; +kfree (dio);return ret;
@@ -371,6 +375,8 @@ static loff_t iomap_dio_hole_iter(const struct iomap_iter *iter,loff_t length =iov_iter_zero (iomap_length (iter), dio->submit.iter); dio->size += length; +if (!length) +return -EFAULT ;return length; }
@@ -402,6 +408,8 @@ static loff_t iomap_dio_inline_iter(const struct iomap_iter *iomi, copied =copy_to_iter (inline_data, length, iter); } dio->size += copied; +if (!copied) +return -EFAULT ;return copied; }
@@ -446,13 +454,21 @@ static loff_t iomap_dio_iter(const struct iomap_iter *iter,* may be pure data writes. In that case, we still need to do a full data sync * completion. * +* When page faults are disabled and @dio_flags includes IOMAP_DIO_PARTIAL, +* __iomap_dio_rw can return a partial result if it encounters a non-resident +* page in @iter after preparing a transfer. In that case, the non-resident +* pages can be faulted in and the request resumed with @done_before set to the +* number of bytes previously transferred. The request will then complete with +* the correct total number of bytes transferred; this is essential for +* completing partial requests asynchronously. +* * Returns -ENOTBLK In case of a page invalidation invalidation failure for * writes. The callers needs to fall back to buffered I/O in this case. */ struct iomap_dio *__iomap_dio_rw (struct kiocb *iocb,struct iov_iter *iter,const struct iomap_ops *ops,const struct iomap_dio_ops *dops, -unsigned int dio_flags) +unsigned int dio_flags,size_t done_before) {struct address_space *mapping = iocb->ki_filp->f_mapping;struct inode *inode =file_inode (iocb->ki_filp);
@@ -482,6 +498,7 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, dio->dops = dops; dio->error =0 ; dio->flags =0 ; + dio->done_before = done_before; dio->submit.iter = iter; dio->submit.waiter = current;
@@ -577,6 +594,12 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,if (iov_iter_rw (iter) ==READ && iomi.pos >= dio->i_size)iov_iter_revert (iter, iomi.pos - dio->i_size); +if (ret == -EFAULT && dio->size && (dio_flags &IOMAP_DIO_PARTIAL )) { +if (!(iocb->ki_flags &IOCB_NOWAIT )) + wait_for_completion = true; + ret =0 ; + } +/* magic error code to fall back to buffered I/O */ if (ret == -ENOTBLK ) { wait_for_completion = true;
@@ -642,11 +665,11 @@ EXPORT_SYMBOL_GPL(__iomap_dio_rw);ssize_t iomap_dio_rw (struct kiocb *iocb,struct iov_iter *iter,const struct iomap_ops *ops,const struct iomap_dio_ops *dops, -unsigned int dio_flags) +unsigned int dio_flags,size_t done_before) {struct iomap_dio *dio; - dio =__iomap_dio_rw (iocb, iter, ops, dops, dio_flags); + dio =__iomap_dio_rw (iocb, iter, ops, dops, dio_flags, done_before);if (IS_ERR_OR_NULL (dio))return PTR_ERR_OR_ZERO (dio);return iomap_dio_complete (dio);
fs/ntfs/file.c +1 -1
@@ -1829,7 +1829,7 @@ static ssize_t ntfs_perform_write(struct file *file, struct iov_iter *i,* pages being swapped out between us bringing them into memory * and doing the actual copying. */ -if (unlikely (iov_iter_fault_in_readable (i, bytes))) { +if (unlikely (fault_in_iov_iter_readable (i, bytes))) { status = -EFAULT ;break ; }
fs/ntfs3/file.c +1 -1
@@ -989,7 +989,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) frame_vbo = pos & ~(frame_size -1 ); index = frame_vbo >>PAGE_SHIFT ; -if (unlikely (iov_iter_fault_in_readable (from, bytes))) { +if (unlikely (fault_in_iov_iter_readable (from, bytes))) { err = -EFAULT ; goto out; }
fs/xfs/xfs_file.c +3 -3
@@ -259,7 +259,7 @@ xfs_file_dio_read( ret =xfs_ilock_iocb (iocb,XFS_IOLOCK_SHARED );if (ret)return ret; - ret =iomap_dio_rw (iocb, to, &xfs_read_iomap_ops,NULL ,0 ); + ret =iomap_dio_rw (iocb, to, &xfs_read_iomap_ops,NULL ,0 ,0 );xfs_iunlock (ip,XFS_IOLOCK_SHARED );return ret;
@@ -569,7 +569,7 @@ xfs_file_dio_write_aligned( }trace_xfs_file_direct_write (iocb, from); ret =iomap_dio_rw (iocb, from, &xfs_direct_write_iomap_ops, - &xfs_dio_write_ops,0 ); + &xfs_dio_write_ops,0 ,0 ); out_unlock:if (iolock)xfs_iunlock (ip, iolock);
@@ -647,7 +647,7 @@ xfs_file_dio_write_unaligned(trace_xfs_file_direct_write (iocb, from); ret =iomap_dio_rw (iocb, from, &xfs_direct_write_iomap_ops, - &xfs_dio_write_ops, flags); + &xfs_dio_write_ops, flags,0 );/* * Retry unaligned I/O with exclusive blocking semantics if the DIO
fs/zonefs/super.c +2 -2
@@ -852,7 +852,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from) ret =zonefs_file_dio_append (iocb, from); else ret =iomap_dio_rw (iocb, from, &zonefs_iomap_ops, - &zonefs_write_dio_ops,0 ); + &zonefs_write_dio_ops,0 ,0 );if (zi->i_ztype ==ZONEFS_ZTYPE_SEQ && (ret >0 || ret == -EIOCBQUEUED )) {if (ret >0 )
@@ -987,7 +987,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) }file_accessed (iocb->ki_filp); ret =iomap_dio_rw (iocb, to, &zonefs_iomap_ops, - &zonefs_read_dio_ops,0 ); + &zonefs_read_dio_ops,0 ,0 ); }else { ret =generic_file_read_iter (iocb, to);if (ret == -EIO )
include/linux/bpf.h +77 -24
174 lines not on this page · raw message
include/linux/bpf_verifier.h +18 -0
@@ -18,6 +18,8 @@* that converting umax_value to int cannot overflow. */ #define BPF_MAX_VAR_SIZ (1 << 29) +/* size of type_str_buf in bpf_verifier. */ +#define TYPE_STR_BUF_LEN 64/* Liveness marks, used for registers and spilled-regs (in stack slots). * Read marks propagate upwards until they find a write mark; they record that
@@ -474,6 +476,8 @@ struct bpf_verifier_env {/* longest register parentage chain walked for liveness marking */ u32 longest_mark_read_walk;bpfptr_t fd_array; +/* buffer used in reg_type_str() to generate reg_type string */ +char type_str_buf[TYPE_STR_BUF_LEN ]; }; __printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log,
@@ -535,4 +539,18 @@ int bpf_check_attach_target(struct bpf_verifier_log *log,u32 btf_id, struct bpf_attach_target_info *tgt_info); +#define BPF_BASE_TYPE_MASK GENMASK(BPF_BASE_TYPE_BITS - 1, 0) + +/* extract base type from bpf_{arg, return, reg}_type. */ +static inline u32 base_type (u32 type) +{ +return type &BPF_BASE_TYPE_MASK ; +} + +/* extract flags from an extended type. See bpf_type_flag in bpf.h. */ +static inline u32 type_flag (u32 type) +{ +return type & ~BPF_BASE_TYPE_MASK ; +} +#endif /* _LINUX_BPF_VERIFIER_H */
include/linux/iomap.h +9 -2
@@ -330,12 +330,19 @@ struct iomap_dio_ops {*/ #define IOMAP_DIO_OVERWRITE_ONLY (1 << 1) +/* +* When a page fault occurs, return a partial synchronous result and allow +* the caller to retry the rest of the operation after dealing with the page +* fault. +*/ +#define IOMAP_DIO_PARTIAL (1 << 2) +ssize_t iomap_dio_rw (struct kiocb *iocb,struct iov_iter *iter,const struct iomap_ops *ops,const struct iomap_dio_ops *dops, -unsigned int dio_flags); +unsigned int dio_flags,size_t done_before);struct iomap_dio *__iomap_dio_rw (struct kiocb *iocb,struct iov_iter *iter,const struct iomap_ops *ops,const struct iomap_dio_ops *dops, -unsigned int dio_flags); +unsigned int dio_flags,size_t done_before);ssize_t iomap_dio_complete (struct iomap_dio *dio);int iomap_dio_iopoll (struct kiocb *kiocb,bool spin);
include/linux/mm.h +2 -1
@@ -2858,7 +2858,8 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,#define FOLL_FORCE 0x10/* get_user_pages read/write w/o permission */ #define FOLL_NOWAIT 0x20/* if a disk transfer is needed, start the IO * and return without waiting upon it */ -#define FOLL_POPULATE 0x40/* fault in page */ +#define FOLL_POPULATE 0x40/* fault in pages (with FOLL_MLOCK) */ +#define FOLL_NOFAULT 0x80/* do not fault in pages */ #define FOLL_HWPOISON 0x100/* check page is hwpoisoned */ #define FOLL_NUMA 0x200/* force NUMA hinting page fault */ #define FOLL_MIGRATION 0x400/* wait for page to replace migration entry */
include/linux/pagemap.h +4 -54
65 lines not on this page · raw message
include/linux/uio.h +3 -1
@@ -35,6 +35,7 @@ struct iov_iter_state {struct iov_iter {u8 iter_type; +bool nofault;bool data_source;size_t iov_offset;size_t count;
@@ -133,7 +134,8 @@ size_t copy_page_from_iter_atomic(struct page *page, unsigned offset, size_t bytes, struct iov_iter *i);void iov_iter_advance (struct iov_iter *i,size_t bytes);void iov_iter_revert (struct iov_iter *i,size_t bytes); -int iov_iter_fault_in_readable (const struct iov_iter *i,size_t bytes); +size_t fault_in_iov_iter_readable (const struct iov_iter *i,size_t bytes); +size_t fault_in_iov_iter_writeable (const struct iov_iter *i,size_t bytes);size_t iov_iter_single_seg_count (const struct iov_iter *i);size_t copy_page_to_iter (struct page *page,size_t offset,size_t bytes,struct iov_iter *i);
kernel/bpf/btf.c +9 -7
@@ -4800,10 +4800,12 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,/* check for PTR_TO_RDONLY_BUF_OR_NULL or PTR_TO_RDWR_BUF_OR_NULL */ for (i =0 ; i < prog->aux->ctx_arg_info_size; i++) {const struct bpf_ctx_arg_aux *ctx_arg_info = &prog->aux->ctx_arg_info[i]; +u32 type, flag; -if (ctx_arg_info->offset == off && - (ctx_arg_info->reg_type ==PTR_TO_RDONLY_BUF_OR_NULL || - ctx_arg_info->reg_type ==PTR_TO_RDWR_BUF_OR_NULL )) { + type =base_type (ctx_arg_info->reg_type); + flag =type_flag (ctx_arg_info->reg_type); +if (ctx_arg_info->offset == off && type ==PTR_TO_BUF && + (flag &PTR_MAYBE_NULL )) { info->reg_type = ctx_arg_info->reg_type;return true; }
@@ -5508,9 +5510,9 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,if (reg->type ==PTR_TO_BTF_ID ) { reg_btf = reg->btf; reg_ref_id = reg->btf_id; - }else if (reg2btf_ids[reg->type]) { + }else if (reg2btf_ids[base_type (reg->type)]) { reg_btf = btf_vmlinux; - reg_ref_id = *reg2btf_ids[reg->type]; + reg_ref_id = *reg2btf_ids[base_type (reg->type)]; }else { bpf_log(log, "kernel function %s args#%d expected pointer to %s %s but R%d is not a pointer to btf_id\n", func_name, i,
@@ -5717,7 +5719,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog,return -EINVAL ; } - reg->type =PTR_TO_MEM_OR_NULL ; + reg->type =PTR_TO_MEM |PTR_MAYBE_NULL ; reg->id = ++env->id_gen;continue ;
@@ -6229,7 +6231,7 @@ const struct bpf_func_proto bpf_btf_find_by_name_kind_proto = { .func = bpf_btf_find_by_name_kind, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM, + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_ANYTHING, .arg4_type = ARG_ANYTHING,
kernel/bpf/cgroup.c +1 -1
@@ -1753,7 +1753,7 @@ static const struct bpf_func_proto bpf_sysctl_set_new_value_proto = { .gpl_only = false, .ret_type = RET_INTEGER, .arg1_type = ARG_PTR_TO_CTX, - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_CONST_SIZE, };
kernel/bpf/helpers.c +6 -6
@@ -530,7 +530,7 @@ const struct bpf_func_proto bpf_strtol_proto = { .func = bpf_strtol, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM, + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_ANYTHING, .arg4_type = ARG_PTR_TO_LONG,
@@ -558,7 +558,7 @@ const struct bpf_func_proto bpf_strtoul_proto = { .func = bpf_strtoul, .gpl_only = false, .ret_type = RET_INTEGER, - .arg1_type = ARG_PTR_TO_MEM, + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg2_type = ARG_CONST_SIZE, .arg3_type = ARG_ANYTHING, .arg4_type = ARG_PTR_TO_LONG,
@@ -630,7 +630,7 @@ const struct bpf_func_proto bpf_event_output_data_proto = { .arg1_type = ARG_PTR_TO_CTX, .arg2_type = ARG_CONST_MAP_PTR, .arg3_type = ARG_ANYTHING, - .arg4_type = ARG_PTR_TO_MEM, + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg5_type = ARG_CONST_SIZE_OR_ZERO, };
@@ -667,7 +667,7 @@ BPF_CALL_2(bpf_per_cpu_ptr, const void *, ptr, u32, cpu)const struct bpf_func_proto bpf_per_cpu_ptr_proto = { .func = bpf_per_cpu_ptr, .gpl_only = false, - .ret_type =RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL , + .ret_type =RET_PTR_TO_MEM_OR_BTF_ID |PTR_MAYBE_NULL |MEM_RDONLY , .arg1_type =ARG_PTR_TO_PERCPU_BTF_ID , .arg2_type =ARG_ANYTHING , };
@@ -680,7 +680,7 @@ BPF_CALL_1(bpf_this_cpu_ptr, const void *, percpu_ptr)const struct bpf_func_proto bpf_this_cpu_ptr_proto = { .func = bpf_this_cpu_ptr, .gpl_only = false, - .ret_type =RET_PTR_TO_MEM_OR_BTF_ID , + .ret_type =RET_PTR_TO_MEM_OR_BTF_ID |MEM_RDONLY , .arg1_type =ARG_PTR_TO_PERCPU_BTF_ID , };
@@ -1013,7 +1013,7 @@ const struct bpf_func_proto bpf_snprintf_proto = { .arg1_type = ARG_PTR_TO_MEM_OR_NULL, .arg2_type = ARG_CONST_SIZE_OR_ZERO, .arg3_type = ARG_PTR_TO_CONST_STR, - .arg4_type = ARG_PTR_TO_MEM_OR_NULL, + .arg4_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, .arg5_type = ARG_CONST_SIZE_OR_ZERO, };
kernel/bpf/map_iter.c +2 -2
@@ -174,9 +174,9 @@ static const struct bpf_iter_reg bpf_map_elem_reg_info = { .ctx_arg_info_size = 2, .ctx_arg_info = { { offsetof(struct bpf_iter__bpf_map_elem, key), - PTR_TO_RDONLY_BUF_OR_NULL }, + PTR_TO_BUF | PTR_MAYBE_NULL | MEM_RDONLY }, { offsetof(struct bpf_iter__bpf_map_elem, value), - PTR_TO_RDWR_BUF_OR_NULL }, + PTR_TO_BUF | PTR_MAYBE_NULL }, }, };
kernel/bpf/ringbuf.c +1 -1
@@ -444,7 +444,7 @@ const struct bpf_func_proto bpf_ringbuf_output_proto = { .func = bpf_ringbuf_output, .ret_type = RET_INTEGER, .arg1_type = ARG_CONST_MAP_PTR, - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_CONST_SIZE_OR_ZERO, .arg4_type = ARG_ANYTHING, };
kernel/bpf/syscall.c +1 -1
@@ -4753,7 +4753,7 @@ static const struct bpf_func_proto bpf_sys_bpf_proto = { .gpl_only = false, .ret_type = RET_INTEGER, .arg1_type = ARG_ANYTHING, - .arg2_type = ARG_PTR_TO_MEM, + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, .arg3_type = ARG_CONST_SIZE, };
kernel/bpf/verifier.c +242 -246
918 lines not on this page · raw message
kernel/trace/bpf_trace.c +11 -11
@@ -345,7 +345,7 @@ static const struct bpf_func_proto bpf_probe_write_user_proto = { .gpl_only = true, .ret_type = RET_INTEGER, .arg1_type = ARG_ANYTHING, - .arg2_type = ARG_PTR_TO_MEM,
Lines of this file are not shown. View the raw message.
lib/iov_iter.c +77 -21
98 lines not on this page · raw message
mm/gup.c +119 -1
120 lines not on this page · raw message
net/core/filter.c +32 -32
64 lines not on this page · raw message
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c +14 -0
Lines of this file are not shown. View the raw message.
tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c new file +29 -0
Lines of this file are not shown. View the raw message.
tools/testing/selftests/bpf/verifier/calls.c +19 -0
Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.