4c30d46517
* refs/heads/tmp-5da1114: Revert crypto changes from android-4.19.79-95 Revert "UPSTREAM: PM / wakeup updates" Revert "ANDROID: of: property: Enable of_devlink by default" Revert "UPSTREAM: dt-bindings: arm: coresight: Add support for coresight-loses-context-with-cpu" UPSTREAM: net: usbnet: Fix -Wcast-function-type UPSTREAM: USB: dummy-hcd: use usb_urb_dir_in instead of usb_pipein UPSTREAM: USB: dummy-hcd: increase max number of devices to 32 ANDROID: tty: serdev: Fix broken serial console input ANDROID: update kernel ABI (perf_event changes) BACKPORT: perf_event: Add support for LSM and SELinux checks UPSTREAM: iommu: Allow io-pgtable to be used outside of drivers/iommu/ ANDROID: update abi for 4.19.94 release ANDROID: update abi due to revert Revert "BACKPORT: perf_event: Add support for LSM and SELinux checks" UPSTREAM: selinux: sidtab reverse lookup hash table UPSTREAM: selinux: avoid atomic_t usage in sidtab UPSTREAM: selinux: check sidtab limit before adding a new entry UPSTREAM: selinux: fix context string corruption in convert_context() UPSTREAM: selinux: overhaul sidtab to fix bug and improve performance UPSTREAM: selinux: refactor mls_context_to_sid() and make it stricter UPSTREAM: selinux: use separate table for initial SID lookup UPSTREAM: selinux: make "selinux_policycap_names[]" const char * UPSTREAM: selinux: refactor sidtab conversion ANDROID: Update ABI representation ANDROID: GKI: clk: Don't disable unused clocks with sync state support ANDROID: GKI: clk: Add support for clock providers with sync state ANDROID: GKI: driver core: Add dev_has_sync_state() ANDROID: update kernel ABI representation BACKPORT: perf_event: Add support for LSM and SELinux checks ANDROID: update ABI representation UPSTREAM: exit: panic before exit_mm() on global init exit ANDROID: serdev: Fix platform device support ANDROID: Kconfig.gki: Add Hidden SPRD DRM configs ANDROID: gki_defconfig: Disable TRANSPARENT_HUGEPAGE ANDROID: gki_defconfig: Enable CONFIG_GNSS_CMDLINE_SERIAL ANDROID: gnss: Add command line test driver ANDROID: serdev: add platform device support ANDROID: gki_defconfig: enable ARM64_SW_TTBR0_PAN ANDROID: gki_defconfig: Set BINFMT_MISC as =m UPSTREAM: binder: fix incorrect calculation for num_valid ABI: Update ABI after f2fs merge ANDROID: add initial ABI whitelist for android-4.19 ANDROID: staging: android: ion: Fix build when CONFIG_ION_SYSTEM_HEAP=n ANDROID: staging: android: ion: Expose total heap and pool sizes via sysfs ANDROID: Update ABI representation due to vmstat counter changes UPSTREAM: include/linux/slab.h: fix sparse warning in kmalloc_type() UPSTREAM: mm, slab: shorten kmalloc cache names for large sizes UPSTREAM: mm, proc: add KReclaimable to /proc/meminfo UPSTREAM: mm: rename and change semantics of nr_indirectly_reclaimable_bytes UPSTREAM: dcache: allocate external names from reclaimable kmalloc caches UPSTREAM: mm, slab/slub: introduce kmalloc-reclaimable caches UPSTREAM: mm, slab: combine kmalloc_caches and kmalloc_dma_caches ANDROID: abi update for 4.19.89 ANDROID: update abi_gki_aarch64.xml for LTO, CFI, and SCS ANDROID: gki_defconfig: enable LTO, CFI, and SCS ANDROID: update abi_gki_aarch64.xml for CONFIG_GNSS ANDROID: cuttlefish_defconfig: Enable CONFIG_GNSS UPSTREAM: arm64: Validate tagged addresses in access_ok() called from kernel threads ANDROID: mm: Throttle rss_stat tracepoint UPSTREAM: mm: slub: really fix slab walking for init_on_free ANDROID: update abi_gki_aarch64.xml for nf change ANDROID: kbuild: limit LTO inlining ANDROID: kbuild: merge module sections with LTO ANDROID: netfilter: nf_nat: remove static from nf_nat_ipv4_fn UPSTREAM: drm/client: remove the exporting of drm_client_close ANDROID: f2fs: fix possible merge of unencrypted with encrypted I/O UPSTREAM: binder: Add binder_proc logging to binderfs UPSTREAM: binder: Make transaction_log available in binderfs UPSTREAM: binder: Add stats, state and transactions files UPSTREAM: binder: add a mount option to show global stats UPSTREAM: binder: Validate the default binderfs device names. UPSTREAM: binder: Add default binder devices through binderfs when configured UPSTREAM: binder: fix CONFIG_ANDROID_BINDER_DEVICES UPSTREAM: android: binder: use kstrdup instead of open-coding it UPSTREAM: binderfs: remove separate device_initcall() UPSTREAM: binderfs: respect limit on binder control creation UPSTREAM: binderfs: switch from d_add() to d_instantiate() UPSTREAM: binderfs: drop lock in binderfs_binder_ctl_create UPSTREAM: binderfs: kill_litter_super() before cleanup UPSTREAM: binderfs: rework binderfs_binder_device_create() UPSTREAM: binderfs: rework binderfs_fill_super() UPSTREAM: binderfs: prevent renaming the control dentry UPSTREAM: binderfs: remove outdated comment UPSTREAM: binderfs: fix error return code in binderfs_fill_super() UPSTREAM: binderfs: handle !CONFIG_IPC_NS builds UPSTREAM: binderfs: reserve devices for initial mount UPSTREAM: binderfs: rename header to binderfs.h UPSTREAM: binderfs: implement "max" mount option UPSTREAM: binderfs: make each binderfs mount a new instance UPSTREAM: binderfs: remove wrong kern_mount() call UPSTREAM: binder: implement binderfs UPSTREAM: binder: remove BINDER_DEBUG_ENTRY() ANDROID: Don't base allmodconfig on gki_defconfig ANDROID: Disable UNWINDER_ORC for allmodconfig ANDROID: update abi_gki_aarch64.xml for 4.19.87 BACKPORT: ARM: 8905/1: Emit __gnu_mcount_nc when using Clang 10.0.0 or newer ANDROID: update abi_gki_aarch64.xml ANDROID: gki_defconfig: =m's applied for virtio configs in arm64 UPSTREAM: of: property: Add device link support for interrupt-parent, dmas and -gpio(s) UPSTREAM: of: property: Add device link support for "iommu-map" UPSTREAM: of: property: Fix the semantics of of_is_ancestor_of() UPSTREAM: i2c: of: Populate fwnode in of_i2c_get_board_info() UPSTREAM: driver core: Clarify documentation for fwnode_operations.add_links() UPSTREAM: dt-bindings: arm: coresight: Add support for coresight-loses-context-with-cpu BACKPORT: coresight: etm4x: Save/restore state across CPU low power states ANDROID: Update ABI representation ANDROID: gki_defconfig: IIO=y f2fs: stop GC when the victim becomes fully valid f2fs: expose main_blkaddr in sysfs f2fs: choose hardlimit when softlimit is larger than hardlimit in f2fs_statfs_project() f2fs: Fix deadlock in f2fs_gc() context during atomic files handling f2fs: show f2fs instance in printk_ratelimited f2fs: fix potential overflow f2fs: fix to update dir's i_pino during cross_rename f2fs: support aligned pinned file f2fs: avoid kernel panic on corruption test f2fs: fix wrong description in document f2fs: cache global IPU bio f2fs: fix to avoid memory leakage in f2fs_listxattr f2fs: check total_segments from devices in raw_super f2fs: update multi-dev metadata in resize_fs f2fs: mark recovery flag correctly in read_raw_super_block() f2fs: fix to update time in lazytime mode vfs: don't allow writes to swap files mm: set S_SWAPFILE on blockdev swap devices BACKPORT: ARM: 8900/1: UNWINDER_FRAME_POINTER implementation for Clang ANDROID: update abi_gki_aarch64.xml for 4.19.87 ANDROID: gki_defconfig: FW_CACHE to no FROMGIT: firmware_class: make firmware caching configurable FROMLIST: arm64: implement Shadow Call Stack FROMLIST: arm64: disable SCS for hypervisor code BACKPORT: FROMLIST: arm64: vdso: disable Shadow Call Stack FROMLIST: arm64: efi: restore x18 if it was corrupted FROMLIST: arm64: preserve x18 when CPU is suspended FROMLIST: arm64: reserve x18 from general allocation with SCS FROMLIST: arm64: disable function graph tracing with SCS FROMLIST: scs: add support for stack usage debugging FROMLIST: scs: add accounting FROMLIST: add support for Clang's Shadow Call Stack (SCS) FROMLIST: arm64: kernel: avoid x18 in __cpu_soft_restart FROMLIST: arm64: kvm: stop treating register x18 as caller save FROMLIST: arm64/lib: copy_page: avoid x18 register in assembler code FROMLIST: arm64: mm: avoid x18 in idmap_kpti_install_ng_mappings ANDROID: use non-canonical CFI jump tables ANDROID: arm64: add __nocfi to __apply_alternatives ANDROID: arm64: add __pa_function ANDROID: arm64: allow ThinLTO to be selected ANDROID: soc/tegra: disable ARCH_TEGRA_210_SOC with LTO FROMLIST: arm64: fix alternatives with LLVM's integrated assembler ANDROID: irqchip/gic-v3: rename gic_of_init to work around a ThinLTO+CFI bug ANDROID: init: ensure initcall ordering with LTO Revert "ANDROID: init: ensure initcall ordering with LTO" ANDROID: add support for ThinLTO ANDROID: clang: update to 10.0.1 ANDROID: gki_defconfig: enable CONFIG_REGULATOR_FIXED_VOLTAGE ANDROID: gki_defconfig: removed CONFIG_PM_WAKELOCKS ANDROID: gki_defconfig: enable CONFIG_IKHEADERS as m FROMGIT: pinctrl: devicetree: Avoid taking direct reference to device name string ANDROID: update abi_gki_aarch64.xml for 4.19.86 update ANDROID: Update ABI representation ANDROID: gki_defconfig: disable FUNCTION_TRACER ANDROID: Update the ABI representation ANDROID: update ABI representation ANDROID: add unstripped modules to the distribution FROMLIST: vsprintf: Inline call to ptr_to_hashval UPSTREAM: rss_stat: Add support to detect RSS updates of external mm UPSTREAM: mm: emit tracepoint when RSS changes FROMGIT: driver core: Allow device link operations inside sync_state() ANDROID: uid_sys_stats: avoid double accounting of dying threads ANDROID: scsi: ufs-qcom: Enable BROKEN_CRYPTO quirk flag ANDROID: scsi: ufs-hisi: Enable BROKEN_CRYPTO quirk flag ANDROID: scsi: ufs: Add quirk bit for controllers that don't play well with inline crypto ANDROID: scsi: ufs: UFS init should not require inline crypto ANDROID: scsi: ufs: UFS crypto variant operations API ANDROID: gki_defconfig: enable inline encryption BACKPORT: FROMLIST: ext4: add inline encryption support BACKPORT: FROMLIST: f2fs: add inline encryption support BACKPORT: FROMLIST: fscrypt: add inline encryption support BACKPORT: FROMLIST: scsi: ufs: Add inline encryption support to UFS BACKPORT: FROMLIST: scsi: ufs: UFS crypto API BACKPORT: FROMLIST: scsi: ufs: UFS driver v2.1 spec crypto additions BACKPORT: FROMLIST: block: blk-crypto for Inline Encryption ANDROID: block: Fix bio_crypt_should_process WARN_ON BACKPORT: FROMLIST: block: Add encryption context to struct bio BACKPORT: FROMLIST: block: Keyslot Manager for Inline Encryption FROMLIST: f2fs: add support for IV_INO_LBLK_64 encryption policies FROMLIST: ext4: add support for IV_INO_LBLK_64 encryption policies BACKPORT: FROMLIST: fscrypt: add support for IV_INO_LBLK_64 policies FROMLIST: fscrypt: zeroize fscrypt_info before freeing FROMLIST: fscrypt: remove struct fscrypt_ctx BACKPORT: FROMLIST: fscrypt: invoke crypto API for ESSIV handling ANDROID: build kernels with llvm-nm and llvm-objcopy ANDROID: Fix allmodconfig build with CC=clang UPSTREAM: mm/page_poison: expose page_poisoning_enabled to kernel modules FROMGIT: of: property: Add device link support for iommus, mboxes and io-channels FROMGIT: of: property: Make it easy to add device links from DT properties FROMGIT: of: property: Minor style clean up of of_link_to_phandle() Revert "ANDROID: of/property: Add device link support for iommus" ANDROID: Add allmodconfig build.configs for x86_64 and aarch64 ANDROID: fix allmodconfig build ANDROID: nf: IDLETIMER: Fix possible use before initialization in idletimer_resume BACKPORT: coresight: funnel: Support static funnel BACKPORT:FROMGIT: coresight: replicator: Fix missing spin_lock_init() BACKPORT:FROMGIT: coresight: funnel: Fix missing spin_lock_init() BACKPORT:FROMGIT: coresight: Serialize enabling/disabling a link device. UPSTREAM: coresight: tmc-etr: Add barrier packets when moving offset forward UPSTREAM: coresight: tmc-etr: Decouple buffer sync and barrier packet insertion UPSTREAM: coresight: tmc: Make memory width mask computation into a function UPSTREAM: coresight: tmc-etr: Fix perf_data check UPSTREAM: coresight: tmc-etr: Fix updating buffer in not-snapshot mode. UPSTREAM: coresight: tmc-etr: Check if non-secure access is enabled UPSTREAM: coresight: tmc-etr: Handle memory errors BACKPORT: coresight: etr_buf: Consolidate refcount initialization UPSTREAM: coresight: Fix DEBUG_LOCKS_WARN_ON for uninitialized attribute UPSTREAM: coresight: Use coresight device names for sinks in PMU attribute UPSTREAM: coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from preemptible UPSTREAM: coresight: tmc-etr: Do not call smp_processor_id() from preemptible UPSTREAM: coresight: perf: Don't set the truncated flag in snapshot mode UPSTREAM: coresight: tmc-etf: Fix snapshot mode update function UPSTREAM: coresight: tmc-etr: Properly set AUX buffer head in snapshot mode UPSTREAM: coresight: tmc-etr: Add support for CPU-wide trace scenarios UPSTREAM: coresight: tmc-etr: Allocate and free ETR memory buffers for CPU-wide scenarios UPSTREAM: coresight: tmc-etr: Introduce the notion of IDR to ETR devices UPSTREAM: coresight: tmc-etr: Introduce the notion of reference counting to ETR devices UPSTREAM: coresight: tmc-etr: Introduce the notion of process ID to ETR devices UPSTREAM: coresight: tmc-etr: Create per-thread buffer allocation function UPSTREAM: coresight: tmc-etr: Refactor function tmc_etr_setup_perf_buf() UPSTREAM: coresight: Communicate perf event to sink buffer allocation functions UPSTREAM: coresight: perf: Refactor function free_event_data() UPSTREAM: coresight: perf: Clean up function etm_setup_aux() UPSTREAM: coresight: Properly address concurrency in sink::update() functions UPSTREAM: coresight: Properly address errors in sink::disable() functions UPSTREAM: coresight: Move reference counting inside sink drivers UPSTREAM: coresight: Adding return code to sink::disable() operation UPSTREAM: coresight: etm4x: Configure tracers to emit timestamps UPSTREAM: coresight: etm4x: Skip selector pair 0 UPSTREAM: coresight: etm4x: Add kernel configuration for CONTEXTID UPSTREAM: coresight: pmu: Adding ITRACE property to cs_etm PMU UPSTREAM: coresight: tmc: Cleanup power management UPSTREAM: coresight: Fix freeing up the coresight connections UPSTREAM: coresight: tmc: Report DMA setup failures UPSTREAM: coresight: catu: fix clang build warning UPSTREAM: perf/core: Fix the address filtering fix UPSTREAM: perf, pt, coresight: Fix address filters for vmas with non-zero offset UPSTREAM: perf: Copy parent's address filter offsets on clone UPSTREAM: coresight: Use event attributes for sink selection UPSTREAM: coresight: perf: Add "sinks" group to PMU directory UPSTREAM: coresight: etb10: Add support for CLAIM tag UPSTREAM: coreisght: tmc: Claim device before use UPSTREAM: coresight: dynamic-replicator: Claim device for use UPSTREAM: coresight: funnel: Claim devices before use UPSTREAM: coresight: etmx: Claim devices before use UPSTREAM: coresight: Add support for CLAIM tag protocol UPSTREAM: coresight: dynamic-replicator: Handle multiple connections UPSTREAM: coresight: etb10: Handle errors enabling the device UPSTREAM: coresight: etm3: Add support for handling errors UPSTREAM: coresight: etm4x: Add support for handling errors UPSTREAM: coresight: tmc-etb/etf: Prepare to handle errors enabling UPSTREAM: coresight: tmc-etr: Handle errors enabling CATU UPSTREAM: coresight: tmc-etr: Refactor for handling errors UPSTREAM: coresight: Handle failures in enabling a trace path UPSTREAM: coresight: tmc: Fix byte-address alignment for RRP UPSTREAM: coresight: etm4x: Configure EL2 exception level when kernel is running in HYP UPSTREAM: coresight: etb10: Splitting function etb_enable() UPSTREAM: coresight: etb10: Refactor etb_drvdata::mode handling UPSTREAM: coresight: etm-perf: Add support for ETR backend UPSTREAM: coresight: perf: Remove set_buffer call back UPSTREAM: coresight: perf: Add helper to retrieve sink configuration UPSTREAM: coresight: perf: Remove reset_buffer call back for sinks UPSTREAM: coresight: Convert driver messages to dev_dbg UPSTREAM: coresight: tmc-etr: Relax collection of trace from sysfs mode UPSTREAM: coresight: tmc-etr: Handle driver mode specific ETR buffers UPSTREAM: coresight: perf: Disable trace path upon source error UPSTREAM: coresight: perf: Allow tracing on hotplugged CPUs UPSTREAM: coresight: perf: Avoid unncessary CPU hotplug read lock UPSTREAM: coresight: perf: Fix per cpu path management UPSTREAM: coresight: Fix handling of sinks UPSTREAM: coresight: Use ERR_CAST instead of ERR_PTR UPSTREAM: coresight: Fix remote endpoint parsing UPSTREAM: coresight: platform: Fix leaking device reference UPSTREAM: coresight: platform: Fix refcounting for graph nodes UPSTREAM: coresight: platform: Refactor graph endpoint parsing UPSTREAM: coresight: Document error handling in coresight_register ANDROID: regression introduced override_creds=off ANDROID: overlayfs: internal getxattr operations without sepolicy checking ANDROID: overlayfs: add __get xattr method ANDROID: Add optional __get xattr method paired to __vfs_getxattr UPSTREAM: scsi: ufs: override auto suspend tunables for ufs UPSTREAM: scsi: core: allow auto suspend override by low-level driver FROMGIT: of: property: Skip adding device links to suppliers that aren't devices ANDROID: gki_defconfig: enable CONFIG_KEYBOARD_GPIO UPSTREAM: dm bufio: introduce a global cache replacement UPSTREAM: dm bufio: remove old-style buffer cleanup UPSTREAM: dm bufio: introduce a global queue UPSTREAM: dm bufio: refactor adjust_total_allocated UPSTREAM: dm bufio: call adjust_total_allocated from __link_buffer and __unlink_buffer ANDROID: dummy_cpufreq: Implement get() ANDROID: gki_defconfig: enable CONFIG_CPUSETS ANDROID: virtio: virtio_input: Set the amount of multitouch slots in virtio input rtlwifi: Fix potential overflow on P2P code ANDROID: cpufreq: create dummy cpufreq driver ANDROID: Allow DRM_IOCTL_MODE_*_DUMB for render clients. Cuttlefish Wifi: Add data ops in virt_wifi driver for scan data simulation ANDROID: of: property: Enable of_devlink by default ANDROID: of: property: Make sure child dependencies don't block probing of parent ANDROID: driver core: Allow fwnode_operations.add_links to differentiate errors ANDROID: driver core: Allow a device to wait on optional suppliers ANDROID: driver core: Add device link support for SYNC_STATE_ONLY flag FROMGIT: docs: driver-model: Add documentation for sync_state FROMGIT: driver: core: Improve documentation for fwnode_operations.add_links() FROMGIT: of: property: Minor code formatting/style clean ups ANDROID: of/property: Add device link support for iommus ANDROID: move up spin_unlock_bh() ahead of remove_proc_entry() BACKPORT: arm64: tags: Preserve tags for addresses translated via TTBR1 UPSTREAM: arm64: memory: Implement __tag_set() as common function UPSTREAM: arm64/mm: fix variable 'tag' set but not used UPSTREAM: arm64: avoid clang warning about self-assignment ANDROID: sdcardfs: evict dentries on fscrypt key removal ANDROID: fscrypt: add key removal notifier chain ANDROID: refactor build.config files to remove duplication ANDROID: Move from clang r353983c to r365631c ANDROID: gki_defconfig: remove PWRSEQ_EMMC and PWRSEQ_SIMPLE ANDROID: unconditionally compile sig_ok in struct module ANDROID: gki_defconfig: enable fs-verity UPSTREAM: mm: vmalloc: show number of vmalloc pages in /proc/meminfo BACKPORT: PM/sleep: Expose suspend stats in sysfs UPSTREAM: power: supply: Init device wakeup after device_add() UPSTREAM: PM / wakeup: Unexport wakeup_source_sysfs_{add,remove}() UPSTREAM: PM / wakeup: Register wakeup class kobj after device is added UPSTREAM: PM / wakeup: Fix sysfs registration error path UPSTREAM: PM / wakeup: Show wakeup sources stats in sysfs UPSTREAM: PM / wakeup: Use wakeup_source_register() in wakelock.c UPSTREAM: PM / wakeup: Drop wakeup_source_init(), wakeup_source_prepare() UPSTREAM: PM / wakeup: Drop wakeup_source_drop() UPSTREAM: PM / core: Add support to skip power management in device/driver model gki_defconfig: Enable CONFIG_DM_SNAPSHOT ANDROID: gki_defconfig: enable accelerated AES and SHA-256 ANDROID: fix overflow in /proc/uid_cputime/remove_uid_range ANDROID: kasan: fix has_attribute check on older GCC versions ANDROID: gki_defconfig: enable CONFIG_PARAVIRT and CONFIG_HYPERVISOR_GUEST ANDROID: gki_defconfig: enable CONFIG_NLS_* ANDROID: gki_defconfig: Enable BPF_JIT and BPF_JIT_ALWAYS_ON FROMGIT: of: property: Create device links for all child-supplier depencencies FROMGIT: of/platform: Pause/resume sync state during init and of_platform_populate() BACKPORT: FROMGIT: driver core: Add sync_state driver/bus callback BACKPORT: FROMGIT: of: property: Add functional dependency link from DT bindings FROMGIT: driver core: Add support for linking devices during device addition FROMGIT: driver core: Add fwnode_to_dev() to look up device from fwnode UPSTREAM: mm: untag user pointers in mmap/munmap/mremap/brk UPSTREAM: vfio/type1: untag user pointers in vaddr_get_pfn UPSTREAM: tee/shm: untag user pointers in tee_shm_register UPSTREAM: media/v4l2-core: untag user pointers in videobuf_dma_contig_user_get UPSTREAM: drm/radeon: untag user pointers in radeon_gem_userptr_ioctl BACKPORT: drm/amdgpu: untag user pointers UPSTREAM: userfaultfd: untag user pointers UPSTREAM: fs/namespace: untag user pointers in copy_mount_options UPSTREAM: mm: untag user pointers in get_vaddr_frames UPSTREAM: mm: untag user pointers in mm/gup.c UPSTREAM: mm: untag user pointers passed to memory syscalls BACKPORT: lib: untag user pointers in strn*_user UPSTREAM: arm64: Fix reference to docs for ARM64_TAGGED_ADDR_ABI UPSTREAM: selftests, arm64: add kernel headers path for tags_test BACKPORT: arm64: Relax Documentation/arm64/tagged-pointers.rst UPSTREAM: arm64: Define Documentation/arm64/tagged-address-abi.rst UPSTREAM: arm64: Change the tagged_addr sysctl control semantics to only prevent the opt-in UPSTREAM: arm64: Tighten the PR_{SET, GET}_TAGGED_ADDR_CTRL prctl() unused arguments UPSTREAM: selftests, arm64: fix uninitialized symbol in tags_test.c UPSTREAM: arm64: mm: Really fix sparse warning in untagged_addr() UPSTREAM: selftests, arm64: add a selftest for passing tagged pointers to kernel BACKPORT: arm64: Introduce prctl() options to control the tagged user addresses ABI UPSTREAM: arm64: untag user pointers in access_ok and __uaccess_mask_ptr UPSTREAM: uaccess: add noop untagged_addr definition BACKPORT: block: annotate refault stalls from IO submission f2fs: add a condition to detect overflow in f2fs_ioc_gc_range() f2fs: fix to add missing F2FS_IO_ALIGNED() condition f2fs: fix to fallback to buffered IO in IO aligned mode f2fs: fix to handle error path correctly in f2fs_map_blocks f2fs: fix extent corrupotion during directIO in LFS mode f2fs: check all the data segments against all node ones f2fs: Add a small clarification to CONFIG_FS_F2FS_FS_SECURITY f2fs: fix inode rwsem regression f2fs: fix to avoid accessing uninitialized field of inode page in is_alive() f2fs: avoid infinite GC loop due to stale atomic files f2fs: Fix indefinite loop in f2fs_gc() f2fs: convert inline_data in prior to i_size_write f2fs: fix error path of f2fs_convert_inline_page() f2fs: add missing documents of reserve_root/resuid/resgid f2fs: fix flushing node pages when checkpoint is disabled f2fs: enhance f2fs_is_checkpoint_ready()'s readability f2fs: clean up __bio_alloc()'s parameter f2fs: fix wrong error injection path in inc_valid_block_count() f2fs: fix to writeout dirty inode during node flush f2fs: optimize case-insensitive lookups f2fs: introduce f2fs_match_name() for cleanup f2fs: Fix indefinite loop in f2fs_gc() f2fs: allocate memory in batch in build_sit_info() f2fs: support FS_IOC_{GET,SET}FSLABEL f2fs: fix to avoid data corruption by forbidding SSR overwrite f2fs: Fix build error while CONFIG_NLS=m Revert "f2fs: avoid out-of-range memory access" f2fs: cleanup the code in build_sit_entries. f2fs: fix wrong available node count calculation f2fs: remove duplicate code in f2fs_file_write_iter f2fs: fix to migrate blocks correctly during defragment f2fs: use wrapped f2fs_cp_error() f2fs: fix to use more generic EOPNOTSUPP f2fs: use wrapped IS_SWAPFILE() f2fs: Support case-insensitive file name lookups f2fs: include charset encoding information in the superblock fs: Reserve flag for casefolding f2fs: fix to avoid call kvfree under spinlock fs: f2fs: Remove unnecessary checks of SM_I(sbi) in update_general_status() f2fs: disallow direct IO in atomic write f2fs: fix to handle quota_{on,off} correctly f2fs: fix to detect cp error in f2fs_setxattr() f2fs: fix to spread f2fs_is_checkpoint_ready() f2fs: support fiemap() for directory inode f2fs: fix to avoid discard command leak f2fs: fix to avoid tagging SBI_QUOTA_NEED_REPAIR incorrectly f2fs: fix to drop meta/node pages during umount f2fs: disallow switching io_bits option during remount f2fs: fix panic of IO alignment feature f2fs: introduce {page,io}_is_mergeable() for readability f2fs: fix livelock in swapfile writes f2fs: add fs-verity support ext4: update on-disk format documentation for fs-verity ext4: add fs-verity read support ext4: add basic fs-verity support fs-verity: support builtin file signatures fs-verity: add SHA-512 support fs-verity: implement FS_IOC_MEASURE_VERITY ioctl fs-verity: implement FS_IOC_ENABLE_VERITY ioctl fs-verity: add data verification hooks for ->readpages() fs-verity: add the hook for file ->setattr() fs-verity: add the hook for file ->open() fs-verity: add inode and superblock fields fs-verity: add Kconfig and the helper functions for hashing fs: uapi: define verity bit for FS_IOC_GETFLAGS fs-verity: add UAPI header fs-verity: add MAINTAINERS file entry fs-verity: add a documentation file ext4: fix kernel oops caused by spurious casefold flag ext4: fix coverity warning on error path of filename setup ext4: optimize case-insensitive lookups ext4: fix dcache lookup of !casefolded directories unicode: update to Unicode 12.1.0 final unicode: add missing check for an error return from utf8lookup() ext4: export /sys/fs/ext4/feature/casefold if Unicode support is present unicode: refactor the rule for regenerating utf8data.h ext4: Support case-insensitive file name lookups ext4: include charset encoding information in the superblock unicode: update unicode database unicode version 12.1.0 unicode: introduce test module for normalized utf8 implementation unicode: implement higher level API for string handling unicode: reduce the size of utf8data[] unicode: introduce code for UTF-8 normalization unicode: introduce UTF-8 character database ext4 crypto: fix to check feature status before get policy fscrypt: document the new ioctls and policy version ubifs: wire up new fscrypt ioctls f2fs: wire up new fscrypt ioctls ext4: wire up new fscrypt ioctls fscrypt: require that key be added when setting a v2 encryption policy fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl fscrypt: allow unprivileged users to add/remove keys for v2 policies fscrypt: v2 encryption policy support fscrypt: add an HKDF-SHA512 implementation fscrypt: add FS_IOC_GET_ENCRYPTION_KEY_STATUS ioctl fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl fscrypt: add FS_IOC_ADD_ENCRYPTION_KEY ioctl fscrypt: rename keyinfo.c to keysetup.c fscrypt: move v1 policy key setup to keysetup_v1.c fscrypt: refactor key setup code in preparation for v2 policies fscrypt: rename fscrypt_master_key to fscrypt_direct_key fscrypt: add ->ci_inode to fscrypt_info fscrypt: use FSCRYPT_* definitions, not FS_* fscrypt: use FSCRYPT_ prefix for uapi constants fs, fscrypt: move uapi definitions to new header <linux/fscrypt.h> fscrypt: use ENOPKG when crypto API support missing fscrypt: improve warnings for missing crypto API support fscrypt: improve warning messages for unsupported encryption contexts fscrypt: make fscrypt_msg() take inode instead of super_block fscrypt: clean up base64 encoding/decoding fscrypt: remove loadable module related code Updated following files to fix build errors: drivers/gpu/msm/kgsl_pool.c drivers/hwtracing/coresight/coresight-dummy.c drivers/iommu/dma-mapping-fast.c drivers/iommu/io-pgtable-fast.c drivers/iommu/io-pgtable-msm-secure.c kernel/taskstats.c mm/vmalloc.c security/selinux/ss/sidtab.h Conflicts: arch/arm/Makefile arch/arm64/Kconfig arch/x86/include/asm/syscall_wrapper.h build.config.common drivers/clk/clk.c drivers/hwtracing/coresight/coresight-etm-perf.c drivers/hwtracing/coresight/coresight-funnel.c drivers/hwtracing/coresight/coresight-tmc-etf.c drivers/hwtracing/coresight/coresight-tmc-etr.c drivers/hwtracing/coresight/coresight-tmc.c drivers/hwtracing/coresight/coresight-tmc.h drivers/hwtracing/coresight/coresight.c drivers/hwtracing/coresight/of_coresight.c drivers/iommu/arm-smmu.c drivers/iommu/io-pgtable-arm.c drivers/iommu/io-pgtable.c drivers/scsi/scsi_sysfs.c drivers/scsi/sd.c drivers/scsi/ufs/ufshcd.c drivers/scsi/ufs/ufshcd.h drivers/staging/android/ion/ion.c drivers/staging/android/ion/ion.h drivers/staging/android/ion/ion_page_pool.c fs/ext4/readpage.c fs/f2fs/data.c fs/f2fs/f2fs.h fs/f2fs/file.c fs/f2fs/segment.c fs/f2fs/super.c include/linux/clk-provider.h include/linux/compiler_types.h include/linux/coresight.h include/linux/mmzone.h include/scsi/scsi_device.h include/trace/events/kmem.h kernel/events/core.c kernel/sched/core.c mm/vmstat.c Change-Id: I2eca52b08b484f2b5c30437671cab8cb0195b8d6 Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
875 lines
23 KiB
C
875 lines
23 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* linux/mm/mlock.c
|
|
*
|
|
* (C) Copyright 1995 Linus Torvalds
|
|
* (C) Copyright 2002 Christoph Hellwig
|
|
*/
|
|
|
|
#include <linux/capability.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/sched/user.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/swapops.h>
|
|
#include <linux/pagemap.h>
|
|
#include <linux/pagevec.h>
|
|
#include <linux/mempolicy.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/export.h>
|
|
#include <linux/rmap.h>
|
|
#include <linux/mmzone.h>
|
|
#include <linux/hugetlb.h>
|
|
#include <linux/memcontrol.h>
|
|
#include <linux/mm_inline.h>
|
|
|
|
#include "internal.h"
|
|
|
|
bool can_do_mlock(void)
|
|
{
|
|
if (rlimit(RLIMIT_MEMLOCK) != 0)
|
|
return true;
|
|
if (capable(CAP_IPC_LOCK))
|
|
return true;
|
|
return false;
|
|
}
|
|
EXPORT_SYMBOL(can_do_mlock);
|
|
|
|
/*
|
|
* Mlocked pages are marked with PageMlocked() flag for efficient testing
|
|
* in vmscan and, possibly, the fault path; and to support semi-accurate
|
|
* statistics.
|
|
*
|
|
* An mlocked page [PageMlocked(page)] is unevictable. As such, it will
|
|
* be placed on the LRU "unevictable" list, rather than the [in]active lists.
|
|
* The unevictable list is an LRU sibling list to the [in]active lists.
|
|
* PageUnevictable is set to indicate the unevictable state.
|
|
*
|
|
* When lazy mlocking via vmscan, it is important to ensure that the
|
|
* vma's VM_LOCKED status is not concurrently being modified, otherwise we
|
|
* may have mlocked a page that is being munlocked. So lazy mlock must take
|
|
* the mmap_sem for read, and verify that the vma really is locked
|
|
* (see mm/rmap.c).
|
|
*/
|
|
|
|
/*
|
|
* LRU accounting for clear_page_mlock()
|
|
*/
|
|
void clear_page_mlock(struct page *page)
|
|
{
|
|
if (!TestClearPageMlocked(page))
|
|
return;
|
|
|
|
mod_zone_page_state(page_zone(page), NR_MLOCK,
|
|
-hpage_nr_pages(page));
|
|
count_vm_event(UNEVICTABLE_PGCLEARED);
|
|
/*
|
|
* The previous TestClearPageMlocked() corresponds to the smp_mb()
|
|
* in __pagevec_lru_add_fn().
|
|
*
|
|
* See __pagevec_lru_add_fn for more explanation.
|
|
*/
|
|
if (!isolate_lru_page(page)) {
|
|
putback_lru_page(page);
|
|
} else {
|
|
/*
|
|
* We lost the race. the page already moved to evictable list.
|
|
*/
|
|
if (PageUnevictable(page))
|
|
count_vm_event(UNEVICTABLE_PGSTRANDED);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Mark page as mlocked if not already.
|
|
* If page on LRU, isolate and putback to move to unevictable list.
|
|
*/
|
|
void mlock_vma_page(struct page *page)
|
|
{
|
|
/* Serialize with page migration */
|
|
BUG_ON(!PageLocked(page));
|
|
|
|
VM_BUG_ON_PAGE(PageTail(page), page);
|
|
VM_BUG_ON_PAGE(PageCompound(page) && PageDoubleMap(page), page);
|
|
|
|
if (!TestSetPageMlocked(page)) {
|
|
mod_zone_page_state(page_zone(page), NR_MLOCK,
|
|
hpage_nr_pages(page));
|
|
count_vm_event(UNEVICTABLE_PGMLOCKED);
|
|
if (!isolate_lru_page(page))
|
|
putback_lru_page(page);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Isolate a page from LRU with optional get_page() pin.
|
|
* Assumes lru_lock already held and page already pinned.
|
|
*/
|
|
static bool __munlock_isolate_lru_page(struct page *page, bool getpage)
|
|
{
|
|
if (PageLRU(page)) {
|
|
struct lruvec *lruvec;
|
|
|
|
lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page));
|
|
if (getpage)
|
|
get_page(page);
|
|
ClearPageLRU(page);
|
|
del_page_from_lru_list(page, lruvec, page_lru(page));
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Finish munlock after successful page isolation
|
|
*
|
|
* Page must be locked. This is a wrapper for try_to_munlock()
|
|
* and putback_lru_page() with munlock accounting.
|
|
*/
|
|
static void __munlock_isolated_page(struct page *page)
|
|
{
|
|
/*
|
|
* Optimization: if the page was mapped just once, that's our mapping
|
|
* and we don't need to check all the other vmas.
|
|
*/
|
|
if (page_mapcount(page) > 1)
|
|
try_to_munlock(page);
|
|
|
|
/* Did try_to_unlock() succeed or punt? */
|
|
if (!PageMlocked(page))
|
|
count_vm_event(UNEVICTABLE_PGMUNLOCKED);
|
|
|
|
putback_lru_page(page);
|
|
}
|
|
|
|
/*
|
|
* Accounting for page isolation fail during munlock
|
|
*
|
|
* Performs accounting when page isolation fails in munlock. There is nothing
|
|
* else to do because it means some other task has already removed the page
|
|
* from the LRU. putback_lru_page() will take care of removing the page from
|
|
* the unevictable list, if necessary. vmscan [page_referenced()] will move
|
|
* the page back to the unevictable list if some other vma has it mlocked.
|
|
*/
|
|
static void __munlock_isolation_failed(struct page *page)
|
|
{
|
|
if (PageUnevictable(page))
|
|
__count_vm_event(UNEVICTABLE_PGSTRANDED);
|
|
else
|
|
__count_vm_event(UNEVICTABLE_PGMUNLOCKED);
|
|
}
|
|
|
|
/**
|
|
* munlock_vma_page - munlock a vma page
|
|
* @page: page to be unlocked, either a normal page or THP page head
|
|
*
|
|
* returns the size of the page as a page mask (0 for normal page,
|
|
* HPAGE_PMD_NR - 1 for THP head page)
|
|
*
|
|
* called from munlock()/munmap() path with page supposedly on the LRU.
|
|
* When we munlock a page, because the vma where we found the page is being
|
|
* munlock()ed or munmap()ed, we want to check whether other vmas hold the
|
|
* page locked so that we can leave it on the unevictable lru list and not
|
|
* bother vmscan with it. However, to walk the page's rmap list in
|
|
* try_to_munlock() we must isolate the page from the LRU. If some other
|
|
* task has removed the page from the LRU, we won't be able to do that.
|
|
* So we clear the PageMlocked as we might not get another chance. If we
|
|
* can't isolate the page, we leave it for putback_lru_page() and vmscan
|
|
* [page_referenced()/try_to_unmap()] to deal with.
|
|
*/
|
|
unsigned int munlock_vma_page(struct page *page)
|
|
{
|
|
int nr_pages;
|
|
struct zone *zone = page_zone(page);
|
|
|
|
/* For try_to_munlock() and to serialize with page migration */
|
|
BUG_ON(!PageLocked(page));
|
|
|
|
VM_BUG_ON_PAGE(PageTail(page), page);
|
|
|
|
/*
|
|
* Serialize with any parallel __split_huge_page_refcount() which
|
|
* might otherwise copy PageMlocked to part of the tail pages before
|
|
* we clear it in the head page. It also stabilizes hpage_nr_pages().
|
|
*/
|
|
spin_lock_irq(zone_lru_lock(zone));
|
|
|
|
if (!TestClearPageMlocked(page)) {
|
|
/* Potentially, PTE-mapped THP: do not skip the rest PTEs */
|
|
nr_pages = 1;
|
|
goto unlock_out;
|
|
}
|
|
|
|
nr_pages = hpage_nr_pages(page);
|
|
__mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
|
|
|
|
if (__munlock_isolate_lru_page(page, true)) {
|
|
spin_unlock_irq(zone_lru_lock(zone));
|
|
__munlock_isolated_page(page);
|
|
goto out;
|
|
}
|
|
__munlock_isolation_failed(page);
|
|
|
|
unlock_out:
|
|
spin_unlock_irq(zone_lru_lock(zone));
|
|
|
|
out:
|
|
return nr_pages - 1;
|
|
}
|
|
|
|
/*
|
|
* convert get_user_pages() return value to posix mlock() error
|
|
*/
|
|
static int __mlock_posix_error_return(long retval)
|
|
{
|
|
if (retval == -EFAULT)
|
|
retval = -ENOMEM;
|
|
else if (retval == -ENOMEM)
|
|
retval = -EAGAIN;
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* Prepare page for fast batched LRU putback via putback_lru_evictable_pagevec()
|
|
*
|
|
* The fast path is available only for evictable pages with single mapping.
|
|
* Then we can bypass the per-cpu pvec and get better performance.
|
|
* when mapcount > 1 we need try_to_munlock() which can fail.
|
|
* when !page_evictable(), we need the full redo logic of putback_lru_page to
|
|
* avoid leaving evictable page in unevictable list.
|
|
*
|
|
* In case of success, @page is added to @pvec and @pgrescued is incremented
|
|
* in case that the page was previously unevictable. @page is also unlocked.
|
|
*/
|
|
static bool __putback_lru_fast_prepare(struct page *page, struct pagevec *pvec,
|
|
int *pgrescued)
|
|
{
|
|
VM_BUG_ON_PAGE(PageLRU(page), page);
|
|
VM_BUG_ON_PAGE(!PageLocked(page), page);
|
|
|
|
if (page_mapcount(page) <= 1 && page_evictable(page)) {
|
|
pagevec_add(pvec, page);
|
|
if (TestClearPageUnevictable(page))
|
|
(*pgrescued)++;
|
|
unlock_page(page);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Putback multiple evictable pages to the LRU
|
|
*
|
|
* Batched putback of evictable pages that bypasses the per-cpu pvec. Some of
|
|
* the pages might have meanwhile become unevictable but that is OK.
|
|
*/
|
|
static void __putback_lru_fast(struct pagevec *pvec, int pgrescued)
|
|
{
|
|
count_vm_events(UNEVICTABLE_PGMUNLOCKED, pagevec_count(pvec));
|
|
/*
|
|
*__pagevec_lru_add() calls release_pages() so we don't call
|
|
* put_page() explicitly
|
|
*/
|
|
__pagevec_lru_add(pvec);
|
|
count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued);
|
|
}
|
|
|
|
/*
|
|
* Munlock a batch of pages from the same zone
|
|
*
|
|
* The work is split to two main phases. First phase clears the Mlocked flag
|
|
* and attempts to isolate the pages, all under a single zone lru lock.
|
|
* The second phase finishes the munlock only for pages where isolation
|
|
* succeeded.
|
|
*
|
|
* Note that the pagevec may be modified during the process.
|
|
*/
|
|
static void __munlock_pagevec(struct pagevec *pvec, struct zone *zone)
|
|
{
|
|
int i;
|
|
int nr = pagevec_count(pvec);
|
|
int delta_munlocked = -nr;
|
|
struct pagevec pvec_putback;
|
|
int pgrescued = 0;
|
|
|
|
pagevec_init(&pvec_putback);
|
|
|
|
/* Phase 1: page isolation */
|
|
spin_lock_irq(zone_lru_lock(zone));
|
|
for (i = 0; i < nr; i++) {
|
|
struct page *page = pvec->pages[i];
|
|
|
|
if (TestClearPageMlocked(page)) {
|
|
/*
|
|
* We already have pin from follow_page_mask()
|
|
* so we can spare the get_page() here.
|
|
*/
|
|
if (__munlock_isolate_lru_page(page, false))
|
|
continue;
|
|
else
|
|
__munlock_isolation_failed(page);
|
|
} else {
|
|
delta_munlocked++;
|
|
}
|
|
|
|
/*
|
|
* We won't be munlocking this page in the next phase
|
|
* but we still need to release the follow_page_mask()
|
|
* pin. We cannot do it under lru_lock however. If it's
|
|
* the last pin, __page_cache_release() would deadlock.
|
|
*/
|
|
pagevec_add(&pvec_putback, pvec->pages[i]);
|
|
pvec->pages[i] = NULL;
|
|
}
|
|
__mod_zone_page_state(zone, NR_MLOCK, delta_munlocked);
|
|
spin_unlock_irq(zone_lru_lock(zone));
|
|
|
|
/* Now we can release pins of pages that we are not munlocking */
|
|
pagevec_release(&pvec_putback);
|
|
|
|
/* Phase 2: page munlock */
|
|
for (i = 0; i < nr; i++) {
|
|
struct page *page = pvec->pages[i];
|
|
|
|
if (page) {
|
|
lock_page(page);
|
|
if (!__putback_lru_fast_prepare(page, &pvec_putback,
|
|
&pgrescued)) {
|
|
/*
|
|
* Slow path. We don't want to lose the last
|
|
* pin before unlock_page()
|
|
*/
|
|
get_page(page); /* for putback_lru_page() */
|
|
__munlock_isolated_page(page);
|
|
unlock_page(page);
|
|
put_page(page); /* from follow_page_mask() */
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Phase 3: page putback for pages that qualified for the fast path
|
|
* This will also call put_page() to return pin from follow_page_mask()
|
|
*/
|
|
if (pagevec_count(&pvec_putback))
|
|
__putback_lru_fast(&pvec_putback, pgrescued);
|
|
}
|
|
|
|
/*
|
|
* Fill up pagevec for __munlock_pagevec using pte walk
|
|
*
|
|
* The function expects that the struct page corresponding to @start address is
|
|
* a non-TPH page already pinned and in the @pvec, and that it belongs to @zone.
|
|
*
|
|
* The rest of @pvec is filled by subsequent pages within the same pmd and same
|
|
* zone, as long as the pte's are present and vm_normal_page() succeeds. These
|
|
* pages also get pinned.
|
|
*
|
|
* Returns the address of the next page that should be scanned. This equals
|
|
* @start + PAGE_SIZE when no page could be added by the pte walk.
|
|
*/
|
|
static unsigned long __munlock_pagevec_fill(struct pagevec *pvec,
|
|
struct vm_area_struct *vma, struct zone *zone,
|
|
unsigned long start, unsigned long end)
|
|
{
|
|
pte_t *pte;
|
|
spinlock_t *ptl;
|
|
|
|
/*
|
|
* Initialize pte walk starting at the already pinned page where we
|
|
* are sure that there is a pte, as it was pinned under the same
|
|
* mmap_sem write op.
|
|
*/
|
|
pte = get_locked_pte(vma->vm_mm, start, &ptl);
|
|
/* Make sure we do not cross the page table boundary */
|
|
end = pgd_addr_end(start, end);
|
|
end = p4d_addr_end(start, end);
|
|
end = pud_addr_end(start, end);
|
|
end = pmd_addr_end(start, end);
|
|
|
|
/* The page next to the pinned page is the first we will try to get */
|
|
start += PAGE_SIZE;
|
|
while (start < end) {
|
|
struct page *page = NULL;
|
|
pte++;
|
|
if (pte_present(*pte))
|
|
page = vm_normal_page(vma, start, *pte);
|
|
/*
|
|
* Break if page could not be obtained or the page's node+zone does not
|
|
* match
|
|
*/
|
|
if (!page || page_zone(page) != zone)
|
|
break;
|
|
|
|
/*
|
|
* Do not use pagevec for PTE-mapped THP,
|
|
* munlock_vma_pages_range() will handle them.
|
|
*/
|
|
if (PageTransCompound(page))
|
|
break;
|
|
|
|
get_page(page);
|
|
/*
|
|
* Increase the address that will be returned *before* the
|
|
* eventual break due to pvec becoming full by adding the page
|
|
*/
|
|
start += PAGE_SIZE;
|
|
if (pagevec_add(pvec, page) == 0)
|
|
break;
|
|
}
|
|
pte_unmap_unlock(pte, ptl);
|
|
return start;
|
|
}
|
|
|
|
/*
|
|
* munlock_vma_pages_range() - munlock all pages in the vma range.'
|
|
* @vma - vma containing range to be munlock()ed.
|
|
* @start - start address in @vma of the range
|
|
* @end - end of range in @vma.
|
|
*
|
|
* For mremap(), munmap() and exit().
|
|
*
|
|
* Called with @vma VM_LOCKED.
|
|
*
|
|
* Returns with VM_LOCKED cleared. Callers must be prepared to
|
|
* deal with this.
|
|
*
|
|
* We don't save and restore VM_LOCKED here because pages are
|
|
* still on lru. In unmap path, pages might be scanned by reclaim
|
|
* and re-mlocked by try_to_{munlock|unmap} before we unmap and
|
|
* free them. This will result in freeing mlocked pages.
|
|
*/
|
|
void munlock_vma_pages_range(struct vm_area_struct *vma,
|
|
unsigned long start, unsigned long end)
|
|
{
|
|
vm_write_begin(vma);
|
|
WRITE_ONCE(vma->vm_flags, vma->vm_flags & VM_LOCKED_CLEAR_MASK);
|
|
vm_write_end(vma);
|
|
|
|
while (start < end) {
|
|
struct page *page;
|
|
unsigned int page_mask = 0;
|
|
unsigned long page_increm;
|
|
struct pagevec pvec;
|
|
struct zone *zone;
|
|
|
|
pagevec_init(&pvec);
|
|
/*
|
|
* Although FOLL_DUMP is intended for get_dump_page(),
|
|
* it just so happens that its special treatment of the
|
|
* ZERO_PAGE (returning an error instead of doing get_page)
|
|
* suits munlock very well (and if somehow an abnormal page
|
|
* has sneaked into the range, we won't oops here: great).
|
|
*/
|
|
page = follow_page(vma, start, FOLL_GET | FOLL_DUMP);
|
|
|
|
if (page && !IS_ERR(page)) {
|
|
if (PageTransTail(page)) {
|
|
VM_BUG_ON_PAGE(PageMlocked(page), page);
|
|
put_page(page); /* follow_page_mask() */
|
|
} else if (PageTransHuge(page)) {
|
|
lock_page(page);
|
|
/*
|
|
* Any THP page found by follow_page_mask() may
|
|
* have gotten split before reaching
|
|
* munlock_vma_page(), so we need to compute
|
|
* the page_mask here instead.
|
|
*/
|
|
page_mask = munlock_vma_page(page);
|
|
unlock_page(page);
|
|
put_page(page); /* follow_page_mask() */
|
|
} else {
|
|
/*
|
|
* Non-huge pages are handled in batches via
|
|
* pagevec. The pin from follow_page_mask()
|
|
* prevents them from collapsing by THP.
|
|
*/
|
|
pagevec_add(&pvec, page);
|
|
zone = page_zone(page);
|
|
|
|
/*
|
|
* Try to fill the rest of pagevec using fast
|
|
* pte walk. This will also update start to
|
|
* the next page to process. Then munlock the
|
|
* pagevec.
|
|
*/
|
|
start = __munlock_pagevec_fill(&pvec, vma,
|
|
zone, start, end);
|
|
__munlock_pagevec(&pvec, zone);
|
|
goto next;
|
|
}
|
|
}
|
|
page_increm = 1 + page_mask;
|
|
start += page_increm * PAGE_SIZE;
|
|
next:
|
|
cond_resched();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* mlock_fixup - handle mlock[all]/munlock[all] requests.
|
|
*
|
|
* Filters out "special" vmas -- VM_LOCKED never gets set for these, and
|
|
* munlock is a no-op. However, for some special vmas, we go ahead and
|
|
* populate the ptes.
|
|
*
|
|
* For vmas that pass the filters, merge/split as appropriate.
|
|
*/
|
|
static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
|
|
unsigned long start, unsigned long end, vm_flags_t newflags)
|
|
{
|
|
struct mm_struct *mm = vma->vm_mm;
|
|
pgoff_t pgoff;
|
|
int nr_pages;
|
|
int ret = 0;
|
|
int lock = !!(newflags & VM_LOCKED);
|
|
vm_flags_t old_flags = vma->vm_flags;
|
|
|
|
if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) ||
|
|
is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm) ||
|
|
vma_is_dax(vma))
|
|
/* don't set VM_LOCKED or VM_LOCKONFAULT and don't count */
|
|
goto out;
|
|
|
|
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
|
|
*prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
|
|
vma->vm_file, pgoff, vma_policy(vma),
|
|
vma->vm_userfaultfd_ctx, vma_get_anon_name(vma));
|
|
if (*prev) {
|
|
vma = *prev;
|
|
goto success;
|
|
}
|
|
|
|
if (start != vma->vm_start) {
|
|
ret = split_vma(mm, vma, start, 1);
|
|
if (ret)
|
|
goto out;
|
|
}
|
|
|
|
if (end != vma->vm_end) {
|
|
ret = split_vma(mm, vma, end, 0);
|
|
if (ret)
|
|
goto out;
|
|
}
|
|
|
|
success:
|
|
/*
|
|
* Keep track of amount of locked VM.
|
|
*/
|
|
nr_pages = (end - start) >> PAGE_SHIFT;
|
|
if (!lock)
|
|
nr_pages = -nr_pages;
|
|
else if (old_flags & VM_LOCKED)
|
|
nr_pages = 0;
|
|
mm->locked_vm += nr_pages;
|
|
|
|
/*
|
|
* vm_flags is protected by the mmap_sem held in write mode.
|
|
* It's okay if try_to_unmap_one unmaps a page just after we
|
|
* set VM_LOCKED, populate_vma_page_range will bring it back.
|
|
*/
|
|
if (lock) {
|
|
vm_write_begin(vma);
|
|
WRITE_ONCE(vma->vm_flags, newflags);
|
|
vm_write_end(vma);
|
|
} else
|
|
munlock_vma_pages_range(vma, start, end);
|
|
|
|
out:
|
|
*prev = vma;
|
|
return ret;
|
|
}
|
|
|
|
static int apply_vma_lock_flags(unsigned long start, size_t len,
|
|
vm_flags_t flags)
|
|
{
|
|
unsigned long nstart, end, tmp;
|
|
struct vm_area_struct * vma, * prev;
|
|
int error;
|
|
|
|
VM_BUG_ON(offset_in_page(start));
|
|
VM_BUG_ON(len != PAGE_ALIGN(len));
|
|
end = start + len;
|
|
if (end < start)
|
|
return -EINVAL;
|
|
if (end == start)
|
|
return 0;
|
|
vma = find_vma(current->mm, start);
|
|
if (!vma || vma->vm_start > start)
|
|
return -ENOMEM;
|
|
|
|
prev = vma->vm_prev;
|
|
if (start > vma->vm_start)
|
|
prev = vma;
|
|
|
|
for (nstart = start ; ; ) {
|
|
vm_flags_t newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
|
|
|
|
newflags |= flags;
|
|
|
|
/* Here we know that vma->vm_start <= nstart < vma->vm_end. */
|
|
tmp = vma->vm_end;
|
|
if (tmp > end)
|
|
tmp = end;
|
|
error = mlock_fixup(vma, &prev, nstart, tmp, newflags);
|
|
if (error)
|
|
break;
|
|
nstart = tmp;
|
|
if (nstart < prev->vm_end)
|
|
nstart = prev->vm_end;
|
|
if (nstart >= end)
|
|
break;
|
|
|
|
vma = prev->vm_next;
|
|
if (!vma || vma->vm_start != nstart) {
|
|
error = -ENOMEM;
|
|
break;
|
|
}
|
|
}
|
|
return error;
|
|
}
|
|
|
|
/*
|
|
* Go through vma areas and sum size of mlocked
|
|
* vma pages, as return value.
|
|
* Note deferred memory locking case(mlock2(,,MLOCK_ONFAULT)
|
|
* is also counted.
|
|
* Return value: previously mlocked page counts
|
|
*/
|
|
static unsigned long count_mm_mlocked_page_nr(struct mm_struct *mm,
|
|
unsigned long start, size_t len)
|
|
{
|
|
struct vm_area_struct *vma;
|
|
unsigned long count = 0;
|
|
|
|
if (mm == NULL)
|
|
mm = current->mm;
|
|
|
|
vma = find_vma(mm, start);
|
|
if (vma == NULL)
|
|
vma = mm->mmap;
|
|
|
|
for (; vma ; vma = vma->vm_next) {
|
|
if (start >= vma->vm_end)
|
|
continue;
|
|
if (start + len <= vma->vm_start)
|
|
break;
|
|
if (vma->vm_flags & VM_LOCKED) {
|
|
if (start > vma->vm_start)
|
|
count -= (start - vma->vm_start);
|
|
if (start + len < vma->vm_end) {
|
|
count += start + len - vma->vm_start;
|
|
break;
|
|
}
|
|
count += vma->vm_end - vma->vm_start;
|
|
}
|
|
}
|
|
|
|
return count >> PAGE_SHIFT;
|
|
}
|
|
|
|
static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t flags)
|
|
{
|
|
unsigned long locked;
|
|
unsigned long lock_limit;
|
|
int error = -ENOMEM;
|
|
|
|
start = untagged_addr(start);
|
|
|
|
if (!can_do_mlock())
|
|
return -EPERM;
|
|
|
|
len = PAGE_ALIGN(len + (offset_in_page(start)));
|
|
start &= PAGE_MASK;
|
|
|
|
lock_limit = rlimit(RLIMIT_MEMLOCK);
|
|
lock_limit >>= PAGE_SHIFT;
|
|
locked = len >> PAGE_SHIFT;
|
|
|
|
if (down_write_killable(¤t->mm->mmap_sem))
|
|
return -EINTR;
|
|
|
|
locked += current->mm->locked_vm;
|
|
if ((locked > lock_limit) && (!capable(CAP_IPC_LOCK))) {
|
|
/*
|
|
* It is possible that the regions requested intersect with
|
|
* previously mlocked areas, that part area in "mm->locked_vm"
|
|
* should not be counted to new mlock increment count. So check
|
|
* and adjust locked count if necessary.
|
|
*/
|
|
locked -= count_mm_mlocked_page_nr(current->mm,
|
|
start, len);
|
|
}
|
|
|
|
/* check against resource limits */
|
|
if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
|
|
error = apply_vma_lock_flags(start, len, flags);
|
|
|
|
up_write(¤t->mm->mmap_sem);
|
|
if (error)
|
|
return error;
|
|
|
|
error = __mm_populate(start, len, 0);
|
|
if (error)
|
|
return __mlock_posix_error_return(error);
|
|
return 0;
|
|
}
|
|
|
|
SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
|
|
{
|
|
return do_mlock(start, len, VM_LOCKED);
|
|
}
|
|
|
|
SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
|
|
{
|
|
vm_flags_t vm_flags = VM_LOCKED;
|
|
|
|
if (flags & ~MLOCK_ONFAULT)
|
|
return -EINVAL;
|
|
|
|
if (flags & MLOCK_ONFAULT)
|
|
vm_flags |= VM_LOCKONFAULT;
|
|
|
|
return do_mlock(start, len, vm_flags);
|
|
}
|
|
|
|
SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
|
|
{
|
|
int ret;
|
|
|
|
start = untagged_addr(start);
|
|
|
|
len = PAGE_ALIGN(len + (offset_in_page(start)));
|
|
start &= PAGE_MASK;
|
|
|
|
if (down_write_killable(¤t->mm->mmap_sem))
|
|
return -EINTR;
|
|
ret = apply_vma_lock_flags(start, len, 0);
|
|
up_write(¤t->mm->mmap_sem);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Take the MCL_* flags passed into mlockall (or 0 if called from munlockall)
|
|
* and translate into the appropriate modifications to mm->def_flags and/or the
|
|
* flags for all current VMAs.
|
|
*
|
|
* There are a couple of subtleties with this. If mlockall() is called multiple
|
|
* times with different flags, the values do not necessarily stack. If mlockall
|
|
* is called once including the MCL_FUTURE flag and then a second time without
|
|
* it, VM_LOCKED and VM_LOCKONFAULT will be cleared from mm->def_flags.
|
|
*/
|
|
static int apply_mlockall_flags(int flags)
|
|
{
|
|
struct vm_area_struct * vma, * prev = NULL;
|
|
vm_flags_t to_add = 0;
|
|
|
|
current->mm->def_flags &= VM_LOCKED_CLEAR_MASK;
|
|
if (flags & MCL_FUTURE) {
|
|
current->mm->def_flags |= VM_LOCKED;
|
|
|
|
if (flags & MCL_ONFAULT)
|
|
current->mm->def_flags |= VM_LOCKONFAULT;
|
|
|
|
if (!(flags & MCL_CURRENT))
|
|
goto out;
|
|
}
|
|
|
|
if (flags & MCL_CURRENT) {
|
|
to_add |= VM_LOCKED;
|
|
if (flags & MCL_ONFAULT)
|
|
to_add |= VM_LOCKONFAULT;
|
|
}
|
|
|
|
for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
|
|
vm_flags_t newflags;
|
|
|
|
newflags = vma->vm_flags & VM_LOCKED_CLEAR_MASK;
|
|
newflags |= to_add;
|
|
|
|
/* Ignore errors */
|
|
mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags);
|
|
cond_resched();
|
|
}
|
|
out:
|
|
return 0;
|
|
}
|
|
|
|
SYSCALL_DEFINE1(mlockall, int, flags)
|
|
{
|
|
unsigned long lock_limit;
|
|
int ret;
|
|
|
|
if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)))
|
|
return -EINVAL;
|
|
|
|
if (!can_do_mlock())
|
|
return -EPERM;
|
|
|
|
lock_limit = rlimit(RLIMIT_MEMLOCK);
|
|
lock_limit >>= PAGE_SHIFT;
|
|
|
|
if (down_write_killable(¤t->mm->mmap_sem))
|
|
return -EINTR;
|
|
|
|
ret = -ENOMEM;
|
|
if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
|
|
capable(CAP_IPC_LOCK))
|
|
ret = apply_mlockall_flags(flags);
|
|
up_write(¤t->mm->mmap_sem);
|
|
if (!ret && (flags & MCL_CURRENT))
|
|
mm_populate(0, TASK_SIZE);
|
|
|
|
return ret;
|
|
}
|
|
|
|
SYSCALL_DEFINE0(munlockall)
|
|
{
|
|
int ret;
|
|
|
|
if (down_write_killable(¤t->mm->mmap_sem))
|
|
return -EINTR;
|
|
ret = apply_mlockall_flags(0);
|
|
up_write(¤t->mm->mmap_sem);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Objects with different lifetime than processes (SHM_LOCK and SHM_HUGETLB
|
|
* shm segments) get accounted against the user_struct instead.
|
|
*/
|
|
static DEFINE_SPINLOCK(shmlock_user_lock);
|
|
|
|
int user_shm_lock(size_t size, struct user_struct *user)
|
|
{
|
|
unsigned long lock_limit, locked;
|
|
int allowed = 0;
|
|
|
|
locked = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
lock_limit = rlimit(RLIMIT_MEMLOCK);
|
|
if (lock_limit == RLIM_INFINITY)
|
|
allowed = 1;
|
|
lock_limit >>= PAGE_SHIFT;
|
|
spin_lock(&shmlock_user_lock);
|
|
if (!allowed &&
|
|
locked + user->locked_shm > lock_limit && !capable(CAP_IPC_LOCK))
|
|
goto out;
|
|
get_uid(user);
|
|
user->locked_shm += locked;
|
|
allowed = 1;
|
|
out:
|
|
spin_unlock(&shmlock_user_lock);
|
|
return allowed;
|
|
}
|
|
|
|
void user_shm_unlock(size_t size, struct user_struct *user)
|
|
{
|
|
spin_lock(&shmlock_user_lock);
|
|
user->locked_shm -= (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
spin_unlock(&shmlock_user_lock);
|
|
free_uid(user);
|
|
}
|