GKI (arm64) relevant 102 out of 584 changes, affecting 165 files +1491/-5944338831b83coredump: Do not lock during 'comm' reporting [1 file, +2/-2]784908004ffs: fix proc_handler for sysctl_nr_open [1 file, +1/-1]f83f330fc4block: retry call probe after request_module in blk_request_module [1 file, +17/-5]e278c7ff75block: check BLK_FEAT_POLL under q_usage_count [2 files, +22/-12]d313ff5308block: don't update BLK_FEAT_POLL in __blk_mq_update_nr_hw_queues [4 files, +22/-26]4621771de1nvme: Add error check for xa_store in nvme_get_effects_log [1 file, +6/-2]e8c390a9a5nvme: Add error path for xa_store in nvme_init_effects [1 file, +22/-4]68303b5d38select: Fix unbalanced user_access_end() [1 file, +2/-2]1e8c151fb2nvme: fix bogus kzalloc() return check in nvme_init_effects_log() [1 file, +1/-1]e4b64d34a4sched/fair: Untangle NEXT_BUDDY and pick_next_task() [2 files, +11/-2]5bb4039f77sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat [2 files, +14/-4]fd2818c5e0sched: Split out __schedule() deactivate task logic into a helper [1 file, +40/-27]3f1215588bsched: psi: pass enqueue/dequeue flags to psi callbacks directly [3 files, +53/-44]10a7d3e734psi: Fix race when task wakes up before psi_sched_switch() adjusts flags [2 files, +7/-3]ebaeca33d3HID: core: Fix assumption that Resolution Multipliers must be in Logical Collections [1 file, +2/-0]7d68c20638OPP: add index check to assert to avoid buffer overflow in _read_freq() [1 file, +27/-15]ff2def2518OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized [1 file, +13/-2]82bd38bd54net_sched: sch_sfq: handle bigger packets [1 file, +13/-26]7d8947f215net_sched: sch_sfq: don't allow 1 packet limit [1 file, +4/-0]e561d1a2baclk: fix an OF node reference leak in of_clk_get_parent_name() [1 file, +3/-1]bd1bb30b9fHID: multitouch: fix support for Goodix PID 0x01e9 [1 file, +1/-1]d474a73856inetpeer: remove create argument of inet_getpeer_v[46]() [7 files, +11/-12]dc4fd82dadinetpeer: remove create argument of inet_getpeer() [2 files, +5/-13]4622e45097inetpeer: update inetpeer timestamp in inet_getpeer() [1 file, +4/-8]9345b588f8inetpeer: do not get a refcount in inet_getpeer() [7 files, +32/-29]4f8344fce9udp: Deal with race between UDP socket address change and rehash [2 files, +106/-0]a7175e363adt-bindings: clock: imx93: Drop IMX93_CLK_END macro definition [1 file, +0/-1]036f2f5109dt-bindings: clock: imx93: Add SPDIF IPG clk [1 file, +1/-0]5078123528regulator: of: Implement the unwind path of of_regulator_match() [1 file, +13/-1]8937f5e38aax25: rcu protect dev->ax25_ptr [7 files, +35/-20]3d62a5037fOPP: OF: Fix an OF node leak in _opp_add_static_v2() [1 file, +3/-1]a3bdd14936HID: fix generic desktop D-Pad controls [2 files, +18/-20]a8251d3a4cmfd: syscon: Fix race in device_node_get_regmap() [1 file, +10/-9]984e7d2aa0wifi: mac80211: Fix common size calculation for ML element [1 file, +3/-8]df2f2d9199Bluetooth: btbcm: Fix NULL deref in btbcm_get_board_name() [1 file, +3/-0]f98ccd7d77dev: Acquire netdev_rename_lock before restoring dev->name in dev_change_name(). [1 file, +2/-0]33e2168788net: let net.core.dev_weight always be non-zero [1 file, +4/-1]b382ab9b88net: avoid race between device unregistration and ethnl ops [1 file, +1/-1]73c7e1d689net: sched: Disallow replacing of child qdisc from one parent to another [1 file, +4/-0]d7fe7e1bbenetfilter: nf_tables: fix set size with rbtree backend [3 files, +96/-2]5213efec90net: sched: refine software bypass handling in tc_run [8 files, +55/-45]a0753466f0tcp_cubic: fix incorrect HyStart round start detection [1 file, +5/-3]b7de862bdacrypto: api - Fix boot-up self-test race [1 file, +2/-2]b002750000bpf: bpf_local_storage: Always use bpf_mem_alloc in PREEMPT_RT [1 file, +6/-2]eb2e58484brhashtable: Fix potential deadlock by moving schedule_work outside lock [1 file, +6/-4]8e7d29b698bpf: Use refcount_t instead of atomic_t for mmap_count [1 file, +4/-4]b777b14c2abpf: Reject struct_ops registration that uses module ptr and the module btf_id is missing [3 files, +26/-5]78b9778349bpf: Send signals asynchronously if !preemptible [1 file, +1/-1]0e272fe6a0bpf: tcp: Mark bpf_load_hdr_opt() arg2 as read-write [1 file, +1/-1]f939008a52rhashtable: Fix rhashtable_try_insert test [1 file, +7/-5]33e47d9573bpf: Cancel the running bpf_timer through kworker for PREEMPT_RT [1 file, +16/-2]6cffdf4838of: property: Avoiding using uninitialized variable @imaplen in parse_interrupt_map() [1 file, +1/-1]92ed1efb6aof: reserved-memory: Do not make kmemleak ignore freed address [1 file, +2/-1]9a0fe62f93of: reserved_mem: Restructure how the reserved memory regions are processed [3 files, +122/-54]e61977c714of/fdt: Restore possibility to use both ACPI and FDT from bootloader [1 file, +1/-9]45e1246e5cPCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy() [1 file, +1/-1]58465dfc42media: uvcvideo: Propagate buf->error to userspace [1 file, +2/-1]a2c80a1881PCI: qcom: Update ICC and OPP values after Link Up event [1 file, +2/-0]a665fab63dPCI: dwc: Always stop link in the dw_pcie_suspend_noirq [1 file, +1/-0]0e0ac81d51scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails [1 file, +1/-0]4896402780erofs: fix potential return value overflow of z_erofs_shrink_scan() [1 file, +1/-2]565611d101module: Extend the preempt disabled section in dereference_symbol_descriptor(). [1 file, +1/-1]fd41b2e9aamodule: Don't fail module loading when setting ro_after_init section RO failed [1 file, +4/-3]1614e75d1adriver core: class: Fix wild pointer dereferences in API class_dev_iter_next() [1 file, +8/-1]b35a3edc7cserial: 8250: Adjust the timeout for FIFO mode [1 file, +26/-6]87fdd4c447xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO [1 file, +6/-4]2a64cff2aaxfrm: Add support for per cpu xfrm state handling. [6 files, +112/-22]aa48a18fdbxfrm: Cache used outbound xfrm states at the policy. [3 files, +71/-0]5e4334dc39xfrm: Add an inbound percpu state cache. [6 files, +70/-7]a16871c783xfrm: state: fix out-of-bounds read during lookup [1 file, +70/-19]6945701ca1xfrm: delete intermediate secpath entry in packet offload mode [1 file, +13/-3]24ac5b7524regulator: core: Add missing newline character [1 file, +1/-1]a099834a51ipmr: do not call mr_mfc_uses_dev() for unres entries [1 file, +0/-3]3b732c60a0PM: hibernate: Add error handling for syscore_suspend() [1 file, +6/-1]e468aace40xfrm: Don't disable preemption while looking up cache state. [1 file, +1/-3]3e44707da8ptp: Properly handle compat ioctls [1 file, +4/-0]a68d7a9fb8ethtool: Fix set RXNFC command with symmetric RSS hash [1 file, +1/-1]a06bb37d65vsock: Allow retrying on connect() failure [1 file, +5/-0]1dd823a46etcp: correct handling of extreme memory squeeze [1 file, +6/-3]557707906dnet: xdp: Disallow attaching device-bound programs in generic mode [1 file, +4/-0]a23834b782genksyms: fix memory leak when the same symbol is added from source [2 files, +15/-2]52f0a28e17genksyms: fix memory leak when the same symbol is read from *.symref file [3 files, +9/-5]206d8e0242io_uring/uring_cmd: use cached cmd_op in io_uring_cmd_sock() [1 file, +1/-1]6e26ca1818kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST [1 file, +4/-2]e4e8ed67e0kconfig: fix memory leak in sym_warn_unmet_dep() [1 file, +1/-0]00d1943fe4f2fs: Introduce linear search for dentries [3 files, +45/-19]e0216c39b4ALSA: usb-audio: Add delay quirk for iBasso DC07 Pro [1 file, +2/-0]f395b7efcenet: usb: rtl8150: enable basic endpoint checking [1 file, +22/-0]ae069cd2bausb: xhci: Fix NULL pointer dereference on certain command aborts [1 file, +2/-1]ebba1bebf0usb: dwc3: core: Defer the probe until USB power supply ready [1 file, +21/-9]01c74aeac2usb: dwc3: Skip resume if pm_runtime_set_active() fails [1 file, +4/-1]ce5c91a1b2usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to PD_T_SENDER_RESPONSE [1 file, +1/-1]15b50cbc6fusb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR PPS [3 files, +16/-8]f2013d19b7remoteproc: core: Fix ida_free call while not allocated [1 file, +7/-7]d1f8e69eecmedia: uvcvideo: Fix double free in error path [1 file, +1/-0]8de4e5a922of: reserved-memory: Warn for missing static reserved memory regions [1 file, +5/-0]698943070edma-mapping: save base/size instead of pointer to shared DMA pool [1 file, +8/-6]78b366aa0exfrm: Add error handling when nla_put_u32() returns an error [1 file, +4/-1]364d7e7f30xfrm: Fix acquire state insertion. [1 file, +1/-0]1cf2177959ethtool: Fix access to uninitialized fields in set RXNFC command [1 file, +2/-1]c3a3741db8memcg: fix soft lockup in the OOM process [2 files, +13/-2]333f128224ethtool: ntuple: fix rss + ring_cookie check [1 file, +1/-1] Changes in 6.12.13 coredump: Do not lock during 'comm' reporting powerpc/book3s64/hugetlb: Fix disabling hugetlb when fadump is active dlm: fix removal of rsb struct that is master and dir record dlm: fix srcu_read_lock() return type to int afs: Fix EEXIST error returned from afs_rmdir() to be ENOTEMPTY afs: Fix directory format encoding struct afs: Fix cleanup of immediately failed async calls fs: fix proc_handler for sysctl_nr_open block: copy back bounce buffer to user-space correctly in case of split block: retry call probe after request_module in blk_request_module ps3disk: Do not use dev->bounce_size before it is set nbd: don't allow reconnect after disconnect pstore/blk: trivial typo fixes block: check BLK_FEAT_POLL under q_usage_count block: don't update BLK_FEAT_POLL in __blk_mq_update_nr_hw_queues nvme-tcp: Fix I/O queue cpu spreading for multiple controllers nvme: Add error check for xa_store in nvme_get_effects_log powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW selftests/powerpc: Fix argument order to timer_sub() nvme: Add error path for xa_store in nvme_init_effects btrfs: improve the warning and error message for btrfs_remove_qgroup() partitions: ldm: remove the initial kernel-doc notation btrfs: subpage: fix the bitmap dump of the locked flags select: Fix unbalanced user_access_end() nvme: fix bogus kzalloc() return check in nvme_init_effects_log() afs: Fix the fallback handling for the YFS.RemoveFile2 RPC call perf/core: Save raw sample data conditionally based on sample type sched/fair: Untangle NEXT_BUDDY and pick_next_task() sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat sched: Fix race between yield_to() and try_to_wake_up() x86/cpu: Enable SD_ASYM_PACKING for PKG domain on AMD x86/topology: Use x86_sched_itmt_flags for PKG domain unconditionally sched: Split out __schedule() deactivate task logic into a helper sched: psi: pass enqueue/dequeue flags to psi callbacks directly psi: Fix race when task wakes up before psi_sched_switch() adjusts flags drm/v3d: Fix performance counter source settings on V3D 7.x drm/rockchip: vop2: fix rk3588 dp+dsi maxclk verification drm/msm/dp: set safe_to_exit_level before printing it drm/msm/hdmi: simplify code in pll_get_integloop_gain drm/etnaviv: Fix page property being used for non writecombine buffers HID: core: Fix assumption that Resolution Multipliers must be in Logical Collections drm/amd/pm: Fix an error handling path in vega10_enable_se_edc_force_stall_config() drm/amdgpu: Fix potential NULL pointer dereference in atomctrl_get_smc_sclk_range_table drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset drm/rockchip: vop2: Fix the mixer alpha setup for layer 0 drm/panthor: Preserve the result returned by panthor_fw_resume() drm/rockchip: vop2: Fix the windows switch between different layers printk: Defer legacy printing when holding printk_cpu_sync drm/connector: Allow clearing HDMI infoframes drm/rockchip: vop2: Set AXI id for rk3588 drm/rockchip: vop2: Setup delay cycle for Esmart2/3 drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8 drm/rockchip: vop2: Add check for 32 bpp format for rk3588 drm/rockchip: vop2: include rockchip_drm_drv.h drm/amdgpu/vcn: reset fw_shared under SRIOV OPP: add index check to assert to avoid buffer overflow in _read_freq() OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized drm/msm/dpu: provide DSPP and correct LM config for SDM670 drm/msm/dpu: link DSPP_2/_3 blocks on SM8150 drm/msm/dpu: link DSPP_2/_3 blocks on SC8180X drm/msm/dpu: link DSPP_2/_3 blocks on SM8250 drm/msm/dpu: link DSPP_2/_3 blocks on SM8350 drm/msm/dpu: link DSPP_2/_3 blocks on SM8550 drm/msm/dpu: link DSPP_2/_3 blocks on SM8650 drm/msm/dpu: link DSPP_2/_3 blocks on X1E80100 drm/msm: Check return value of of_dma_configure() drm/msm: don't clean up priv->kms prematurely drm/msm/mdp4: correct LCDC regulator name drm/bridge: it6505: Change definition of AUX_FIFO_MAX_SIZE drm/amdgpu: tear down ttm range manager for doorbell in amdgpu_ttm_fini() Revert "drm/amdgpu/gfx9: put queue resets behind a debug option" drm/amdgpu: fix gpu recovery disable with per queue reset genirq: Make handle_enforce_irqctx() unconditionally available ipmi: ipmb: Add check devm_kasprintf() returned value wifi: ath11k: Fix unexpected return buffer manager error for WCN6750/WCN6855 wifi: rtlwifi: rtl8821ae: phy: restore removed code to fix infinite loop wifi: rtlwifi: do not complete firmware loading needlessly wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last step wifi: rtlwifi: wait for firmware loading before releasing memory wifi: rtlwifi: fix init_sw_vars leak when probe fails wifi: rtlwifi: usb: fix workqueue leak when probe fails wifi: wcn36xx: fix channel survey memory allocation size clk: renesas: cpg-mssr: Fix 'soc' node handling in cpg_mssr_reserved_init() wifi: cfg80211: tests: Fix potential NULL dereference in test_cfg80211_parse_colocated_ap() selftests/bpf: Actuate tx_metadata_len in xdp_hw_metadata net_sched: sch_sfq: handle bigger packets net_sched: sch_sfq: don't allow 1 packet limit spi: zynq-qspi: Add check for clk_enable() rxrpc: Fix handling of received connection abort dt-bindings: mmc: controller: clarify the address-cells description clk: fix an OF node reference leak in of_clk_get_parent_name() dt-bindings: leds: class-multicolor: Fix path to color definitions wifi: rtlwifi: remove unused check_buddy_priv wifi: rtlwifi: destroy workqueue at rtl_deinit_core wifi: rtlwifi: fix memory leaks and invalid access at probe error path wifi: rtlwifi: pci: wait for firmware loading before releasing memory HID: multitouch: fix support for Goodix PID 0x01e9 regulator: dt-bindings: mt6315: Drop regulator-compatible property wifi: brcmfmac: add missing header include for brcmf_dbg module: Convert default symbol namespace to string literal hwmon: (nct6775): Actually make use of the HWMON_NCT6775 symbol namespace ACPI: fan: cleanup resources in the error path of .probe() cpupower: fix TSC MHz calculation dt-bindings: mfd: bd71815: Fix rsense and typos leds: netxbig: Fix an OF node reference leak in netxbig_leds_get_of_pdata() inetpeer: remove create argument of inet_getpeer_v[46]() inetpeer: remove create argument of inet_getpeer() inetpeer: update inetpeer timestamp in inet_getpeer() inetpeer: do not get a refcount in inet_getpeer() pwm: stm32-lp: Add check for clk_enable() cpufreq: schedutil: Fix superfluous updates caused by need_freq_update selftests: ktap_helpers: Fix uninitialized variable ptr_ring: do not block hard interrupts in ptr_ring_resize_multiple() net: airoha: Fix error path in airoha_probe() gpio: pca953x: log an error when failing to get the reset GPIO cpufreq: qcom: Fix qcom_cpufreq_hw_recalc_rate() to query LUT if LMh IRQ is not available cpufreq: qcom: Implement clk_ops::determine_rate() for qcom_cpufreq* clocks udp: Deal with race between UDP socket address change and rehash clk: imx8mp: Fix clkout1/2 support dt-bindings: clock: imx93: Drop IMX93_CLK_END macro definition dt-bindings: clock: Add i.MX91 clock support dt-bindings: clock: imx93: Add SPDIF IPG clk clk: imx93: Move IMX93_CLK_END macro to clk driver clk: imx: add i.MX91 clk clk: imx93: Add IMX93_CLK_SPDIF_IPG clock arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as SPDIF IPG clock clk: imx: Apply some clks only for i.MX93 clk: qcom: camcc-x1e80100: Set titan_top_gdsc as the parent GDSC of subordinate GDSCs team: prevent adding a device which is already a team device lower dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI clk: sunxi-ng: a64: drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL_MIPI clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent regulator: of: Implement the unwind path of of_regulator_match() ax25: rcu protect dev->ax25_ptr net/mlx5: HWS, fix definer's HWS_SET32 macro for negative offset OPP: OF: Fix an OF node leak in _opp_add_static_v2() ipmi: ssif_bmc: Fix new request loss when bmc ready for a response wifi: ath12k: fix tx power, max reg power update to firmware clk: qcom: gcc-sdm845: Do not use shared clk_ops for QUPs HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding endpoint check HID: fix generic desktop D-Pad controls leds: cht-wcove: Use devm_led_classdev_register() to avoid memory leak mfd: syscon: Fix race in device_node_get_regmap() samples/landlock: Fix possible NULL dereference in parse_path() wifi: mt76: mt7996: fix invalid interface combinations wifi: wlcore: fix unbalanced pm_runtime calls wifi: rtw89: handle entity active flag per PHY wifi: rtw89: chan: manage active interfaces wifi: rtw89: tweak setting of channel and TX power for MLO wifi: rtw89: fix proceeding MCC with wrong scanning state after sequence changes wifi: rtw89: chan: fix soft lockup in rtw89_entity_recalc_mgnt_roles() wifi: rtw89: avoid to init mgnt_entry list twice when WoWLAN failed wifi: rtw89: mcc: consider time limits not divisible by 1024 wifi: rtw89: fix race between cancel_hw_scan and hw_scan completion hwmon: Fix help text for aspeed-g6-pwm-tach wifi: mt76: mt7925: fix off by one in mt7925_load_clc() wifi: mt76: mt7915: Fix mesh scan on MT7916 DBDC wifi: iwlwifi: fw: read STEP table from correct UEFI var wifi: iwlwifi: mvm: avoid NULL pointer dereference wifi: iwlwifi: mvm: don't count mgmt frames as MPDU wifi: mac80211: prohibit deactivating all links wifi: cfg80211: Move cfg80211_scan_req_add_chan() n_channels increment earlier wifi: mac80211: fix tid removal during mesh forwarding wifi: mac80211: Fix common size calculation for ML element wifi: mac80211: don't flush non-uploaded STAs clk: ralink: mtmips: remove duplicated 'xtal' clock for Ralink SoC RT3883 clk: thead: Fix clk gate registration to pass flags clk: thead: Add CLK_IGNORE_UNUSED to fix TH1520 boot clk: thead: Fix cpu2vp_clk for TH1520 AP_SUBSYS clocks net/smc: fix data error when recvmsg with MSG_PEEK flag landlock: Handle weird files wifi: mt76: mt76u_vendor_request: Do not print error messages when -EPROTO wifi: mt76: mt7921: fix using incorrect group cipher after disconnection. wifi: mt76: mt7915: Fix an error handling path in mt7915_add_interface() wifi: mt76: mt7925: fix NULL deref check in mt7925_change_vif_links wifi: mt76: mt7925: fix wrong band_idx setting when enable sniffer mode wifi: mt76: mt7925: fix get wrong chip cap from incorrect pointer wifi: mt76: mt7925: fix the invalid ip address for arp offload wifi: mt76: mt7996: fix overflows seen when writing limit attributes wifi: mt76: mt7915: fix overflows seen when writing limit attributes wifi: mt76: connac: Extend mt76_connac_mcu_uni_add_dev for MLO wifi: mt76: mt7925: Fix incorrect MLD address in bss_mld_tlv for MLO support wifi: mt76: mt7925: Fix incorrect WCID assignment for MLO wifi: mt76: mt7925: Fix incorrect WCID phy_idx assignment wifi: mt76: mt7925: fix wrong parameter for related cmd of chan info wifi: mt76: mt7925: Fix CNM Timeout with Single Active Link in MLO wifi: mt76: mt7925: Enhance mt7925_mac_link_bss_add to support MLO wifi: mt76: Enhance mt7925_mac_link_sta_add to support MLO wifi: mt76: mt7925: Update mt7925_mcu_sta_update for BC in ASSOC state wifi: mt76: mt7925: Update mt792x_rx_get_wcid for per-link STA wifi: mt76: mt7925: Update mt7925_unassign_vif_chanctx for per-link BSS wifi: mt76: mt7925: Update secondary link PS flow wifi: mt76: mt7925: Init secondary link PM state wifi: mt76: mt7925: Update mt7925_mcu_uni_[tx,rx]_ba for MLO wifi: mt76: mt7925: Cleanup MLO settings post-disconnection wifi: mt76: mt7925: Properly handle responses for commands with events wifi: mt76: mt7996: fix rx filter setting for bfee functionality wifi: mt76: only enable tx worker after setting the channel wifi: mt76: mt7915: firmware restart on devices with a second pcie link wifi: mt76: mt7915: fix omac index assignment after hardware reset wifi: mt76: mt7915: fix register mapping wifi: mt76: mt7996: fix register mapping wifi: mt76: mt7996: add max mpdu len capability wifi: mt76: mt7996: fix the capability of reception of EHT MU PPDU wifi: mt76: mt7996: fix HE Phy capability wifi: mt76: mt7996: fix incorrect indexing of MIB FW event wifi: mt76: mt7996: fix definition of tx descriptor wifi: mt76: mt7996: fix ldpc setting i2c: designware: Actually make use of the I2C_DW_COMMON and I2C_DW symbol namespaces cpufreq: ACPI: Fix max-frequency computation selftests: timers: clocksource-switch: Adapt progress to kselftest framework selftests: harness: fix printing of mismatch values in __EXPECT() wifi: cfg80211: adjust allocation of colocated AP data Bluetooth: btbcm: Fix NULL deref in btbcm_get_board_name() Bluetooth: btrtl: check for NULL in btrtl_setup_realtek() inet: ipmr: fix data-races clk: analogbits: Fix incorrect calculation of vco rate delta dev: Acquire netdev_rename_lock before restoring dev->name in dev_change_name(). pwm: stm32: Add check for clk_enable() selftests/landlock: Fix build with non-default pthread linking selftests/landlock: Fix error message net: let net.core.dev_weight always be non-zero net/mlxfw: Drop hard coded max FW flash image size octeon_ep: remove firmware stats fetch in ndo_get_stats64 octeon_ep_vf: remove firmware stats fetch in ndo_get_stats64 net: avoid race between device unregistration and ethnl ops net: sched: Disallow replacing of child qdisc from one parent to another netfilter: nf_tables: fix set size with rbtree backend netfilter: nft_flow_offload: update tcp state flags under lock net: sched: refine software bypass handling in tc_run net: ethernet: ti: am65-cpsw: fix freeing IRQ in am65_cpsw_nuss_remove_tx_chns() tcp_cubic: fix incorrect HyStart round start detection net/rose: prevent integer overflows in rose_setsockopt() platform/mellanox: mlxbf-pmc: incorrect type in assignment platform/x86: x86-android-tablets: make platform data be static pinctrl: samsung: Fix irq handling if an error occurs in exynos_irq_demux_eint16_31() libbpf: don't adjust USDT semaphore address if .stapsdt.base addr is missing ASoC: cs40l50: Use *-y for Makefile ASoC: mediatek: mt8365: Use *-y for Makefile ASoC: wcd937x: Use *-y for Makefile tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind libbpf: Fix segfault due to libelf functions not setting errno ASoC: Intel: sof_sdw: correct mach_params->dmic_num ASoC: sun4i-spdif: Add clock multiplier settings selftests/bpf: Fix fill_link_info selftest on powerpc iommu/arm-smmuv3: Update comments about ATS and bypass crypto: tegra - do not transfer req when tegra init fails crypto: api - Fix boot-up self-test race crypto: caam - use JobR's space to access page 0 regs perf header: Fix one memory leakage in process_bpf_btf() perf header: Fix one memory leakage in process_bpf_prog_info() perf bpf: Fix two memory leakages when calling perf_env__insert_bpf_prog_info() ASoC: renesas: rz-ssi: Use only the proper amount of dividers perf expr: Initialize is_test value in expr__ctx_new() pinctrl: nomadik: Add check for clk_enable() ktest.pl: Remove unused declarations in run_bisect_test function bpf: bpf_local_storage: Always use bpf_mem_alloc in PREEMPT_RT rhashtable: Fix potential deadlock by moving schedule_work outside lock crypto: hisilicon/sec2 - fix for aead icv error crypto: hisilicon/sec2 - fix for aead invalid authsize crypto: ixp4xx - fix OF node reference leaks in init_ixp_crypto() crypto: iaa - Fix IAA disabling that occurs when sync_mode is set to 'async' bpf: Use refcount_t instead of atomic_t for mmap_count ALSA: seq: Make dependency on UMP clearer bpf: Reject struct_ops registration that uses module ptr and the module btf_id is missing padata: fix sysfs store callback check selftests/bpf: Avoid generating untracked files when running bpf selftests perf top: Don't complain about lack of vmlinux when not resolving some kernel samples perf maps: Fix display of kernel symbols perf machine: Don't ignore _etext when not a text symbol perf namespaces: Introduce nsinfo__set_in_pidns() perf namespaces: Fixup the nsinfo__in_pidns() return type, its bool ASoC: Intel: avs: Do not readq() u32 registers ASoC: Intel: avs: Fix the minimum firmware version numbers ASoC: Intel: avs: Fix theoretical infinite loop ASoC: Intel: avs: Fix init-config parsing perf MANIFEST: Add arch/*/include/uapi/asm/bpf_perf_event.h to the perf tarball ALSA: hda: Fix compilation of snd_hdac_adsp_xxx() helpers perf report: Fix misleading help message about --demangle pinctrl: stm32: Add check for clk_enable() pinctrl: amd: Take suspend type into consideration which pins are non-wake perf inject: Fix use without initialization of local variables ASoC: Intel: sof_sdw: Fix DMI match for Lenovo 83LC ASoC: Intel: sof_sdw: Fix DMI match for Lenovo 83JX, 83MC and 83NM bpf: Send signals asynchronously if !preemptible selftests/bpf: Fix btf leak on new btf alloc failure in btf_distill test libbpf: Fix return zero when elf_begin failed libbpf: Fix incorrect traversal end type ID when marking BTF_IS_EMBEDDED bpf: tcp: Mark bpf_load_hdr_opt() arg2 as read-write iommu/amd: Remove unused amd_iommu_domain_update() ALSA: hda/realtek - Fixed headphone distorted sound on Acer Aspire A115-31 laptop tools: Sync if_xdp.h uapi tooling header perf lock: Fix parse_lock_type which only retrieve one lock flag padata: fix UAF in padata_reorder padata: add pd get/put refcnt helper padata: avoid UAF for reorder_work rhashtable: Fix rhashtable_try_insert test smb: client: fix oops due to unset link speed cifs: Use cifs_autodisable_serverino() for disabling CIFS_MOUNT_SERVER_INUM in readdir.c bpf: Cancel the running bpf_timer through kworker for PREEMPT_RT soc: atmel: fix device_node release in atmel_soc_device_init() ARM: at91: pm: change BU Power Switch to automatic mode ARM: dts: imx7-tqma7: add missing vs-supply for LM75A (rev. 01xxx) arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to get working suspend arm64: dts: mt8183: set DMIC one-wire mode on Damu arm64: dts: mediatek: mt8516: fix GICv2 range arm64: dts: mediatek: mt8516: fix wdt irq type arm64: dts: mediatek: mt8516: add i2c clock-div property arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A ARM: dts: stm32: Increase CPU core voltage on STM32MP13xx DHCOR SoM ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151 RDMA/mlx4: Avoid false error about access to uninitialized gids array arm64: dts: renesas: rzg3s-smarc: Fix the debug serial alias rdma/cxgb4: Prevent potential integer overflow on 32bit arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property arm64: dts: medaitek: mt8395-nio-12l: Drop regulator-compatible property arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible property arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names ARM: dts: aspeed: yosemite4: correct the compatible string of adm1272 ARM: dts: aspeed: yosemite4: Add required properties for IOE on fan boards ARM: dts: aspeed: yosemite4: correct the compatible string for max31790 arm: dts: socfpga: use reset-name "stmmaceth-ocp" instead of "ahb" RDMA/rxe: Fix mismatched max_msg_sz arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen arm64: dts: mediatek: mt8183: willow: Support second source touchscreen RDMA/srp: Fix error handling in srp_add_port arm64: dts: mediatek: mt8195: Remove suspend-breaking reset from pcie1 ARM: dts: stm32: Deduplicate serial aliases and chosen node for STM32MP15xx DHCOM SoM ARM: dts: stm32: Swap USART3 and UART8 alias on STM32MP15xx DHCOM SoM memory: tegra20-emc: fix an OF node reference bug in tegra_emc_find_node_by_ram_code() arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop pp3300_panel voltage settings arm64: dts: qcom: msm8996-xiaomi-gemini: Fix LP5562 LED1 reg property arm64: dts: qcom: sa8775p: Update sleep_clk frequency arm64: defconfig: remove obsolete CONFIG_SM_DISPCC_8650 arm64: dts: qcom: msm8996: Fix up USB3 interrupts arm64: dts: qcom: msm8994: Describe USB interrupts arm64: dts: qcom: sm7225-fairphone-fp4: Drop extra qcom,msm-id value arm64: dts: qcom: msm8916: correct sleep clock frequency arm64: dts: qcom: msm8939: correct sleep clock frequency arm64: dts: qcom: msm8994: correct sleep clock frequency arm64: dts: qcom: qcs404: correct sleep clock frequency arm64: dts: qcom: q[dr]u1000: correct sleep clock frequency arm64: dts: qcom: qrb4210-rb2: correct sleep clock frequency arm64: dts: qcom: sc7280: correct sleep clock frequency arm64: dts: qcom: sdx75: correct sleep clock frequency arm64: dts: qcom: sm4450: correct sleep clock frequency arm64: dts: qcom: sm6125: correct sleep clock frequency arm64: dts: qcom: sm6375: correct sleep clock frequency arm64: dts: qcom: sm8250: correct sleep clock frequency arm64: dts: qcom: sm8350: correct sleep clock frequency arm64: dts: qcom: sm8450: correct sleep clock frequency arm64: dts: qcom: sm8550: correct sleep clock frequency arm64: dts: qcom: sm8650: correct sleep clock frequency arm64: dts: qcom: x1e80100: correct sleep clock frequency arm64: dts: qcom: sm8650: Fix CDSP context banks unit addresses ARM: dts: microchip: sama5d29_curiosity: Add no-1-8-v property to sdmmc0 node ARM: dts: microchip: sama5d27_wlsom1_ek: Add no-1-8-v property to sdmmc0 node arm64: dts: ti: k3-am62: Remove duplicate GICR reg arm64: dts: ti: k3-am62a: Remove duplicate GICR reg arm64: dts: rockchip: Fix sdmmc access on rk3308-rock-s0 v1.1 boards arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0 RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error RDMA/rtrs: Add missing deinit() call RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS ARM: omap1: Fix up the Retu IRQ on Nokia 770 arm64: dts: qcom: qcm6490-shift-otter: remove invalid orientation-switch arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: Convert mezzanine riser to dtso arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: remove disabled ov7251 camera arm64: dts: qcom: sc7180-trogdor-quackingstick: add missing avee-supply arm64: dts: qcom: sc7180-trogdor-pompom: rename 5v-choke thermal zone arm64: dts: qcom: sc7180: change labels to lower-case arm64: dts: qcom: sc7180: fix psci power domain node names arm64: dts: qcom: sm8150-microsoft-surface-duo: fix typos in da7280 properties arm64: dts: qcom: sc8280xp: Fix up remoteproc register space sizes firmware: qcom: scm: Cleanup global '__scm' on probe failures arm64: dts: mediatek: mt7988: Add missing clock-div property for i2c dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL arm64: dts: mediatek: add per-SoC compatibles for keypad nodes arm64: dts: qcom: sc8280xp: Fix interrupt type of camss interrupts arm64: dts: qcom: sdm845: Fix interrupt types of camss interrupts arm64: dts: qcom: sm8250: Fix interrupt types of camss interrupts arm64: dts: marvell: cn9131-cf-solidwan: fix cp1 comphy links ARM: dts: mediatek: mt7623: fix IR nodename arm64: dts: rockchip: fix num-channels property of wolfvision pf5 mic arm64: dts: ti: k3-am642-hummingboard-t: Convert overlay to board dts fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device() arm64: tegra: Fix DMA ID for SPI2 arm64: dts: qcom: x1e80100-romulus: Update firmware nodes i3c: dw: Fix use-after-free in dw_i3c_master driver due to race condition RDMA/mlx5: Fix indirect mkey ODP page count of: property: Avoiding using uninitialized variable @imaplen in parse_interrupt_map() of: reserved-memory: Do not make kmemleak ignore freed address efi: sysfb_efi: fix W=1 warnings when EFI is not set RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]" iommu: iommufd: fix WARNING in iommufd_device_unbind iommufd/iova_bitmap: Fix shift-out-of-bounds in iova_bitmap_offset_to_index() spi: omap2-mcspi: Correctly handle devm_clk_get_optional() errors of: reserved_mem: Restructure how the reserved memory regions are processed of/fdt: Restore possibility to use both ACPI and FDT from bootloader media: rc: iguanair: handle timeouts media: lmedm04: Handle errors for lme2510_int_read PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy() remoteproc: mtk_scp: Only populate devices for SCP cores media: marvell: Add check for clk_enable() media: i2c: imx290: Register 0x3011 varies between imx327 and imx290 media: i2c: imx412: Add missing newline to prints media: i2c: ov9282: Correct the exposure offset media: mipi-csis: Add check for clk_enable() media: camif-core: Add check for clk_enable() media: uvcvideo: Propagate buf->error to userspace mtd: rawnand: brcmnand: fix status read of brcmnand_waitfunc mtd: hyperbus: hbmc-am654: fix an OF node reference leak media: nxp: imx8-isi: fix v4l2-compliance test errors watchdog: rti_wdt: Fix an OF node leak in rti_wdt_probe() staging: media: imx: fix OF node leak in imx_media_add_of_subdevs() media: dvb-usb-v2: af9035: fix ISO C90 compilation error on af9035_i2c_master_xfer PCI: rcar-ep: Fix incorrect variable used when calling devm_request_mem_region() PCI: imx6: Configure PHY based on Root Complex or Endpoint mode PCI: imx6: Skip controller_id generation logic for i.MX7D PCI: imx6: Deassert apps_reset in imx_pcie_deassert_core_reset() PCI: imx6: Add missing reference clock disable logic PCI: qcom: Update ICC and OPP values after Link Up event PCI: dwc: Always stop link in the dw_pcie_suspend_noirq PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test PCI: microchip: Add support for using either Root Port 1 or 2 PCI: microchip: Set inbound address translation for coherent or non-coherent mode scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1 scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails scsi: mpi3mr: Fix possible crash when setting up bsg fails firewire: test: Fix potential null dereference in firewire kunit test erofs: get rid of erofs_{find,insert}_workgroup erofs: move erofs_workgroup operations into zdata.c erofs: sunset `struct erofs_workgroup` erofs: fix potential return value overflow of z_erofs_shrink_scan() ocfs2: mark dquot as inactive if failed to start trans while releasing dquot nilfs2: do not force clear folio if buffer is referenced nilfs2: protect access to buffers with no active references nilfs2: handle errors that nilfs_prepare_chunk() may return module: Extend the preempt disabled section in dereference_symbol_descriptor(). module: Don't fail module loading when setting ro_after_init section RO failed driver core: class: Fix wild pointer dereferences in API class_dev_iter_next() tty: mips_ejtag_fdc: fix one more u8 warning serial: 8250: Adjust the timeout for FIFO mode nfs: fix incorrect error handling in LOCALIO NFSv4.2: fix COPY_NOTIFY xdr buf size calculation NFSv4.2: mark OFFLOAD_CANCEL MOVEABLE LoongArch: Fix warnings during S3 suspend tools/bootconfig: Fix the wrong format specifier xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO xfrm: Add support for per cpu xfrm state handling. xfrm: Cache used outbound xfrm states at the policy. xfrm: Add an inbound percpu state cache. xfrm: state: fix out-of-bounds read during lookup dmaengine: ti: edma: fix OF node reference leaks in edma_driver xfrm: delete intermediate secpath entry in packet offload mode rtc: tps6594: Fix integer overflow on 32bit systems rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr() ubifs: skip dumping tnc tree when zroot is null regulator: core: Add missing newline character net: airoha: Fix wrong GDM4 register definition net: hns3: fix oops when unload drivers paralleling gpio: mxc: remove dead code after switch to DT-only net: phy: marvell-88q2xxx: Fix temperature measurement with reset-gpios net: fec: implement TSO descriptor cleanup ipmr: do not call mr_mfc_uses_dev() for unres entries PM: hibernate: Add error handling for syscore_suspend() perf trace: Fix BPF loading failure (-E2BIG) xfrm: Don't disable preemption while looking up cache state. idpf: add read memory barrier when checking descriptor done bit idpf: fix transaction timeouts on reset idpf: Acquire the lock before accessing the xn->salt idpf: convert workqueues to unbound ice: fix ice_parser_rt::bst_key array size ice: rework of dump serdes equalizer values feature ice: extend dump serdes equalizer values feature ice: remove invalid parameter of equalizer iavf: allow changing VLAN state without calling PF s390/mm: Allow large pages for KASAN shadow mapping net/ncsi: use dev_set_mac_address() for Get MC MAC Address handling net: rose: fix timer races against user threads net: netdevsim: try to close UDP port harness races tools: ynl: c: correct reverse decode of empty attrs selftests: mptcp: extend CFLAGS to keep options from environment selftests: net/{lib,openvswitch}: extend CFLAGS to keep options from environment rxrpc, afs: Fix peer hash locking vs RCU callback vxlan: Fix uninit-value in vxlan_vnifilter_dump() net: davicom: fix UAF in dm9000_drv_remove ptp: Properly handle compat ioctls net: ethtool: only allow set_rxnfc with rss + ring_cookie if driver opts in ethtool: Fix set RXNFC command with symmetric RSS hash net: stmmac: Limit the number of MTL queues to hardware capability net: stmmac: Limit FIFO size by hardware capability s390/sclp: Initialize sclp subsystem via arch_cpu_finalize_init() perf trace: Fix runtime error of index out of bounds perf test: Skip syscall enum test if no landlock syscall Bluetooth: btusb: mediatek: Add locks for usb_driver_claim_interface() Bluetooth: btnxpuart: Fix glitches seen in dual A2DP streaming vsock: Allow retrying on connect() failure bgmac: reduce max frame size to support just MTU 1500 tcp: correct handling of extreme memory squeeze net: xdp: Disallow attaching device-bound programs in generic mode net: ravb: Fix missing rtnl lock in suspend/resume path net: sh_eth: Fix missing rtnl lock in suspend/resume path net: hsr: fix fill_frame_info() regression vs VLAN packets genksyms: fix memory leak when the same symbol is added from source genksyms: fix memory leak when the same symbol is read from *.symref file hostfs: fix string handling in __dentry_name() tools/power turbostat: Allow using cpu device in perf counters on hybrid platforms tools/power turbostat: Fix PMT mmaped file size rounding RISC-V: Mark riscv_v_init() as __init ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback io_uring/uring_cmd: use cached cmd_op in io_uring_cmd_sock() ASoC: amd: acp: Fix possible deadlock tools/power turbostat: Fix forked child affinity regression cifs: Validate EAs for WSL reparse points cifs: Fix getting and setting SACLs over SMB1 kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST kconfig: fix memory leak in sym_warn_unmet_dep() hexagon: fix using plain integer as NULL pointer warning in cmpxchg hexagon: Fix unbalanced spinlock in die() f2fs: Introduce linear search for dentries md/md-bitmap: factor behind write counters out from bitmap_{start/end}write() md/md-bitmap: remove the last parameter for bimtap_ops->endwrite() md: add a new callback pers->bitmap_sector() md/raid5: implement pers->bitmap_sector() md/md-bitmap: move bitmap_{start, end}write to md upper layer Revert "SUNRPC: Reduce thread wake-up rate when receiving large RPC messages" kbuild: switch from lz4c to lz4 for compression netfilter: nf_tables: reject mismatching sum of field_len with set key length drm/amd/display: Reduce accessing remote DPCD overhead selftests/rseq: Fix handling of glibc without rseq support selftests/ftrace: Fix to use remount when testing mount GID option ktest.pl: Check kernelrelease return in get_version xfs: check for dead buffers in xfs_buf_find_insert xfs: don't shut down the filesystem for media failures beyond end of log ALSA: usb-audio: Add delay quirk for iBasso DC07 Pro net: usb: rtl8150: enable basic endpoint checking usb: xhci: Fix NULL pointer dereference on certain command aborts drivers/card_reader/rtsx_usb: Restore interrupt based detection usb: gadget: f_tcm: Fix Get/SetInterface return value usb: dwc3-am62: Fix an OF node leak in phy_syscon_pll_refclk() usb: dwc3: core: Defer the probe until USB power supply ready usb: dwc3: Skip resume if pm_runtime_set_active() fails usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to PD_T_SENDER_RESPONSE usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR PPS clk: qcom: gcc-x1e80100: Do not turn off usb_2 controller GDSC mptcp: consolidate suboption status mptcp: pm: only set fullmesh for subflow endp mptcp: handle fastopen disconnect correctly mptcp: blackhole only if 1st SYN retrans w/o MPC is accepted RDMA/mlx5: Fix implicit ODP use after free remoteproc: core: Fix ida_free call while not allocated media: uvcvideo: Fix double free in error path pps: Fix a use-after-free usb: gadget: f_tcm: Don't free command immediately staging: media: max96712: fix kernel oops when removing module media: imx-jpeg: Fix potential error pointer dereference in detach_pm() powerpc/pseries/iommu: Don't unset window if it was never set md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime btrfs: output the reason for open_ctree() failure of: reserved-memory: Warn for missing static reserved memory regions dma-mapping: save base/size instead of pointer to shared DMA pool xfrm: Add error handling when nla_put_u32() returns an error xfrm: Fix acquire state insertion. ethtool: Fix access to uninitialized fields in set RXNFC command Revert "s390/mm: Allow large pages for KASAN shadow mapping" selftests/bpf: Add test to verify tailcall and freplace restrictions ASoC: da7213: Initialize the mutex s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS drm/amd/display: Add hubp cache reset when powergating KVM: x86: Plumb in the vCPU to kvm_x86_ops.hwapic_isr_update() memcg: fix soft lockup in the OOM process LoongArch: Change 8 to 14 for LOONGARCH_MAX_{BRP,WRP} btrfs: do proper folio cleanup when run_delalloc_nocow() failed ethtool: ntuple: fix rss + ring_cookie check Linux 6.12.13 Change-Id: I0b4278d2911ea7c72e068418ed56d1514b393980 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
1450 lines
35 KiB
C
1450 lines
35 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* This file contains the procedures for the handling of select and poll
|
|
*
|
|
* Created for Linux based loosely upon Mathius Lattner's minix
|
|
* patches by Peter MacDonald. Heavily edited by Linus.
|
|
*
|
|
* 4 February 1994
|
|
* COFF/ELF binary emulation. If the process has the STICKY_TIMEOUTS
|
|
* flag set in its personality we do *not* modify the given timeout
|
|
* parameter to reflect time remaining.
|
|
*
|
|
* 24 January 2000
|
|
* Changed sys_poll()/do_poll() to use PAGE_SIZE chunk-based allocation
|
|
* of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian).
|
|
*/
|
|
|
|
#include <linux/compat.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/sched/signal.h>
|
|
#include <linux/sched/rt.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/export.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/poll.h>
|
|
#include <linux/personality.h> /* for STICKY_TIMEOUTS */
|
|
#include <linux/file.h>
|
|
#include <linux/fdtable.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/rcupdate.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/freezer.h>
|
|
#include <net/busy_poll.h>
|
|
#include <linux/vmalloc.h>
|
|
|
|
#include <linux/uaccess.h>
|
|
|
|
|
|
/*
|
|
* Estimate expected accuracy in ns from a timeval.
|
|
*
|
|
* After quite a bit of churning around, we've settled on
|
|
* a simple thing of taking 0.1% of the timeout as the
|
|
* slack, with a cap of 100 msec.
|
|
* "nice" tasks get a 0.5% slack instead.
|
|
*
|
|
* Consider this comment an open invitation to come up with even
|
|
* better solutions..
|
|
*/
|
|
|
|
#define MAX_SLACK (100 * NSEC_PER_MSEC)
|
|
|
|
static long __estimate_accuracy(struct timespec64 *tv)
|
|
{
|
|
long slack;
|
|
int divfactor = 1000;
|
|
|
|
if (tv->tv_sec < 0)
|
|
return 0;
|
|
|
|
if (task_nice(current) > 0)
|
|
divfactor = divfactor / 5;
|
|
|
|
if (tv->tv_sec > MAX_SLACK / (NSEC_PER_SEC/divfactor))
|
|
return MAX_SLACK;
|
|
|
|
slack = tv->tv_nsec / divfactor;
|
|
slack += tv->tv_sec * (NSEC_PER_SEC/divfactor);
|
|
|
|
if (slack > MAX_SLACK)
|
|
return MAX_SLACK;
|
|
|
|
return slack;
|
|
}
|
|
|
|
u64 select_estimate_accuracy(struct timespec64 *tv)
|
|
{
|
|
u64 ret;
|
|
struct timespec64 now;
|
|
u64 slack = current->timer_slack_ns;
|
|
|
|
if (slack == 0)
|
|
return 0;
|
|
|
|
ktime_get_ts64(&now);
|
|
now = timespec64_sub(*tv, now);
|
|
ret = __estimate_accuracy(&now);
|
|
if (ret < slack)
|
|
return slack;
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
struct poll_table_page {
|
|
struct poll_table_page * next;
|
|
struct poll_table_entry * entry;
|
|
struct poll_table_entry entries[];
|
|
};
|
|
|
|
#define POLL_TABLE_FULL(table) \
|
|
((unsigned long)((table)->entry+1) > PAGE_SIZE + (unsigned long)(table))
|
|
|
|
/*
|
|
* Ok, Peter made a complicated, but straightforward multiple_wait() function.
|
|
* I have rewritten this, taking some shortcuts: This code may not be easy to
|
|
* follow, but it should be free of race-conditions, and it's practical. If you
|
|
* understand what I'm doing here, then you understand how the linux
|
|
* sleep/wakeup mechanism works.
|
|
*
|
|
* Two very simple procedures, poll_wait() and poll_freewait() make all the
|
|
* work. poll_wait() is an inline-function defined in <linux/poll.h>,
|
|
* as all select/poll functions have to call it to add an entry to the
|
|
* poll table.
|
|
*/
|
|
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
|
|
poll_table *p);
|
|
|
|
void poll_initwait(struct poll_wqueues *pwq)
|
|
{
|
|
init_poll_funcptr(&pwq->pt, __pollwait);
|
|
pwq->polling_task = current;
|
|
pwq->triggered = 0;
|
|
pwq->error = 0;
|
|
pwq->table = NULL;
|
|
pwq->inline_index = 0;
|
|
}
|
|
EXPORT_SYMBOL(poll_initwait);
|
|
|
|
static void free_poll_entry(struct poll_table_entry *entry)
|
|
{
|
|
remove_wait_queue(entry->wait_address, &entry->wait);
|
|
fput(entry->filp);
|
|
}
|
|
|
|
void poll_freewait(struct poll_wqueues *pwq)
|
|
{
|
|
struct poll_table_page * p = pwq->table;
|
|
int i;
|
|
for (i = 0; i < pwq->inline_index; i++)
|
|
free_poll_entry(pwq->inline_entries + i);
|
|
while (p) {
|
|
struct poll_table_entry * entry;
|
|
struct poll_table_page *old;
|
|
|
|
entry = p->entry;
|
|
do {
|
|
entry--;
|
|
free_poll_entry(entry);
|
|
} while (entry > p->entries);
|
|
old = p;
|
|
p = p->next;
|
|
free_page((unsigned long) old);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(poll_freewait);
|
|
|
|
static struct poll_table_entry *poll_get_entry(struct poll_wqueues *p)
|
|
{
|
|
struct poll_table_page *table = p->table;
|
|
|
|
if (p->inline_index < N_INLINE_POLL_ENTRIES)
|
|
return p->inline_entries + p->inline_index++;
|
|
|
|
if (!table || POLL_TABLE_FULL(table)) {
|
|
struct poll_table_page *new_table;
|
|
|
|
new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL);
|
|
if (!new_table) {
|
|
p->error = -ENOMEM;
|
|
return NULL;
|
|
}
|
|
new_table->entry = new_table->entries;
|
|
new_table->next = table;
|
|
p->table = new_table;
|
|
table = new_table;
|
|
}
|
|
|
|
return table->entry++;
|
|
}
|
|
|
|
static int __pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
|
|
{
|
|
struct poll_wqueues *pwq = wait->private;
|
|
DECLARE_WAITQUEUE(dummy_wait, pwq->polling_task);
|
|
|
|
/*
|
|
* Although this function is called under waitqueue lock, LOCK
|
|
* doesn't imply write barrier and the users expect write
|
|
* barrier semantics on wakeup functions. The following
|
|
* smp_wmb() is equivalent to smp_wmb() in try_to_wake_up()
|
|
* and is paired with smp_store_mb() in poll_schedule_timeout.
|
|
*/
|
|
smp_wmb();
|
|
pwq->triggered = 1;
|
|
|
|
/*
|
|
* Perform the default wake up operation using a dummy
|
|
* waitqueue.
|
|
*
|
|
* TODO: This is hacky but there currently is no interface to
|
|
* pass in @sync. @sync is scheduled to be removed and once
|
|
* that happens, wake_up_process() can be used directly.
|
|
*/
|
|
return default_wake_function(&dummy_wait, mode, sync, key);
|
|
}
|
|
|
|
static int pollwake(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
|
|
{
|
|
struct poll_table_entry *entry;
|
|
|
|
entry = container_of(wait, struct poll_table_entry, wait);
|
|
if (key && !(key_to_poll(key) & entry->key))
|
|
return 0;
|
|
return __pollwake(wait, mode, sync, key);
|
|
}
|
|
|
|
/* Add a new entry */
|
|
static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
|
|
poll_table *p)
|
|
{
|
|
struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt);
|
|
struct poll_table_entry *entry = poll_get_entry(pwq);
|
|
if (!entry)
|
|
return;
|
|
entry->filp = get_file(filp);
|
|
entry->wait_address = wait_address;
|
|
entry->key = p->_key;
|
|
init_waitqueue_func_entry(&entry->wait, pollwake);
|
|
entry->wait.private = pwq;
|
|
add_wait_queue(wait_address, &entry->wait);
|
|
}
|
|
|
|
static int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
|
|
ktime_t *expires, unsigned long slack)
|
|
{
|
|
int rc = -EINTR;
|
|
|
|
set_current_state(state);
|
|
if (!pwq->triggered)
|
|
rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS);
|
|
__set_current_state(TASK_RUNNING);
|
|
|
|
/*
|
|
* Prepare for the next iteration.
|
|
*
|
|
* The following smp_store_mb() serves two purposes. First, it's
|
|
* the counterpart rmb of the wmb in pollwake() such that data
|
|
* written before wake up is always visible after wake up.
|
|
* Second, the full barrier guarantees that triggered clearing
|
|
* doesn't pass event check of the next iteration. Note that
|
|
* this problem doesn't exist for the first iteration as
|
|
* add_wait_queue() has full barrier semantics.
|
|
*/
|
|
smp_store_mb(pwq->triggered, 0);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* poll_select_set_timeout - helper function to setup the timeout value
|
|
* @to: pointer to timespec64 variable for the final timeout
|
|
* @sec: seconds (from user space)
|
|
* @nsec: nanoseconds (from user space)
|
|
*
|
|
* Note, we do not use a timespec for the user space value here, That
|
|
* way we can use the function for timeval and compat interfaces as well.
|
|
*
|
|
* Returns -EINVAL if sec/nsec are not normalized. Otherwise 0.
|
|
*/
|
|
int poll_select_set_timeout(struct timespec64 *to, time64_t sec, long nsec)
|
|
{
|
|
struct timespec64 ts = {.tv_sec = sec, .tv_nsec = nsec};
|
|
|
|
if (!timespec64_valid(&ts))
|
|
return -EINVAL;
|
|
|
|
/* Optimize for the zero timeout value here */
|
|
if (!sec && !nsec) {
|
|
to->tv_sec = to->tv_nsec = 0;
|
|
} else {
|
|
ktime_get_ts64(to);
|
|
*to = timespec64_add_safe(*to, ts);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
enum poll_time_type {
|
|
PT_TIMEVAL = 0,
|
|
PT_OLD_TIMEVAL = 1,
|
|
PT_TIMESPEC = 2,
|
|
PT_OLD_TIMESPEC = 3,
|
|
};
|
|
|
|
static int poll_select_finish(struct timespec64 *end_time,
|
|
void __user *p,
|
|
enum poll_time_type pt_type, int ret)
|
|
{
|
|
struct timespec64 rts;
|
|
|
|
restore_saved_sigmask_unless(ret == -ERESTARTNOHAND);
|
|
|
|
if (!p)
|
|
return ret;
|
|
|
|
if (current->personality & STICKY_TIMEOUTS)
|
|
goto sticky;
|
|
|
|
/* No update for zero timeout */
|
|
if (!end_time->tv_sec && !end_time->tv_nsec)
|
|
return ret;
|
|
|
|
ktime_get_ts64(&rts);
|
|
rts = timespec64_sub(*end_time, rts);
|
|
if (rts.tv_sec < 0)
|
|
rts.tv_sec = rts.tv_nsec = 0;
|
|
|
|
|
|
switch (pt_type) {
|
|
case PT_TIMEVAL:
|
|
{
|
|
struct __kernel_old_timeval rtv;
|
|
|
|
if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
|
|
memset(&rtv, 0, sizeof(rtv));
|
|
rtv.tv_sec = rts.tv_sec;
|
|
rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
|
|
if (!copy_to_user(p, &rtv, sizeof(rtv)))
|
|
return ret;
|
|
}
|
|
break;
|
|
case PT_OLD_TIMEVAL:
|
|
{
|
|
struct old_timeval32 rtv;
|
|
|
|
rtv.tv_sec = rts.tv_sec;
|
|
rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;
|
|
if (!copy_to_user(p, &rtv, sizeof(rtv)))
|
|
return ret;
|
|
}
|
|
break;
|
|
case PT_TIMESPEC:
|
|
if (!put_timespec64(&rts, p))
|
|
return ret;
|
|
break;
|
|
case PT_OLD_TIMESPEC:
|
|
if (!put_old_timespec32(&rts, p))
|
|
return ret;
|
|
break;
|
|
default:
|
|
BUG();
|
|
}
|
|
/*
|
|
* If an application puts its timeval in read-only memory, we
|
|
* don't want the Linux-specific update to the timeval to
|
|
* cause a fault after the select has completed
|
|
* successfully. However, because we're not updating the
|
|
* timeval, we can't restart the system call.
|
|
*/
|
|
|
|
sticky:
|
|
if (ret == -ERESTARTNOHAND)
|
|
ret = -EINTR;
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* Scalable version of the fd_set.
|
|
*/
|
|
|
|
typedef struct {
|
|
unsigned long *in, *out, *ex;
|
|
unsigned long *res_in, *res_out, *res_ex;
|
|
} fd_set_bits;
|
|
|
|
/*
|
|
* How many longwords for "nr" bits?
|
|
*/
|
|
#define FDS_BITPERLONG (8*sizeof(long))
|
|
#define FDS_LONGS(nr) (((nr)+FDS_BITPERLONG-1)/FDS_BITPERLONG)
|
|
#define FDS_BYTES(nr) (FDS_LONGS(nr)*sizeof(long))
|
|
|
|
/*
|
|
* Use "unsigned long" accesses to let user-mode fd_set's be long-aligned.
|
|
*/
|
|
static inline
|
|
int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
|
|
{
|
|
nr = FDS_BYTES(nr);
|
|
if (ufdset)
|
|
return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0;
|
|
|
|
memset(fdset, 0, nr);
|
|
return 0;
|
|
}
|
|
|
|
static inline unsigned long __must_check
|
|
set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
|
|
{
|
|
if (ufdset)
|
|
return __copy_to_user(ufdset, fdset, FDS_BYTES(nr));
|
|
return 0;
|
|
}
|
|
|
|
static inline
|
|
void zero_fd_set(unsigned long nr, unsigned long *fdset)
|
|
{
|
|
memset(fdset, 0, FDS_BYTES(nr));
|
|
}
|
|
|
|
#define FDS_IN(fds, n) (fds->in + n)
|
|
#define FDS_OUT(fds, n) (fds->out + n)
|
|
#define FDS_EX(fds, n) (fds->ex + n)
|
|
|
|
#define BITS(fds, n) (*FDS_IN(fds, n)|*FDS_OUT(fds, n)|*FDS_EX(fds, n))
|
|
|
|
static int max_select_fd(unsigned long n, fd_set_bits *fds)
|
|
{
|
|
unsigned long *open_fds;
|
|
unsigned long set;
|
|
int max;
|
|
struct fdtable *fdt;
|
|
|
|
/* handle last in-complete long-word first */
|
|
set = ~(~0UL << (n & (BITS_PER_LONG-1)));
|
|
n /= BITS_PER_LONG;
|
|
fdt = files_fdtable(current->files);
|
|
open_fds = fdt->open_fds + n;
|
|
max = 0;
|
|
if (set) {
|
|
set &= BITS(fds, n);
|
|
if (set) {
|
|
if (!(set & ~*open_fds))
|
|
goto get_max;
|
|
return -EBADF;
|
|
}
|
|
}
|
|
while (n) {
|
|
open_fds--;
|
|
n--;
|
|
set = BITS(fds, n);
|
|
if (!set)
|
|
continue;
|
|
if (set & ~*open_fds)
|
|
return -EBADF;
|
|
if (max)
|
|
continue;
|
|
get_max:
|
|
do {
|
|
max++;
|
|
set >>= 1;
|
|
} while (set);
|
|
max += n * BITS_PER_LONG;
|
|
}
|
|
|
|
return max;
|
|
}
|
|
|
|
#define POLLIN_SET (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN | EPOLLHUP | EPOLLERR |\
|
|
EPOLLNVAL)
|
|
#define POLLOUT_SET (EPOLLWRBAND | EPOLLWRNORM | EPOLLOUT | EPOLLERR |\
|
|
EPOLLNVAL)
|
|
#define POLLEX_SET (EPOLLPRI | EPOLLNVAL)
|
|
|
|
static inline void wait_key_set(poll_table *wait, unsigned long in,
|
|
unsigned long out, unsigned long bit,
|
|
__poll_t ll_flag)
|
|
{
|
|
wait->_key = POLLEX_SET | ll_flag;
|
|
if (in & bit)
|
|
wait->_key |= POLLIN_SET;
|
|
if (out & bit)
|
|
wait->_key |= POLLOUT_SET;
|
|
}
|
|
|
|
static noinline_for_stack int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
|
|
{
|
|
ktime_t expire, *to = NULL;
|
|
struct poll_wqueues table;
|
|
poll_table *wait;
|
|
int retval, i, timed_out = 0;
|
|
u64 slack = 0;
|
|
__poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0;
|
|
unsigned long busy_start = 0;
|
|
|
|
rcu_read_lock();
|
|
retval = max_select_fd(n, fds);
|
|
rcu_read_unlock();
|
|
|
|
if (retval < 0)
|
|
return retval;
|
|
n = retval;
|
|
|
|
poll_initwait(&table);
|
|
wait = &table.pt;
|
|
if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
|
|
wait->_qproc = NULL;
|
|
timed_out = 1;
|
|
}
|
|
|
|
if (end_time && !timed_out)
|
|
slack = select_estimate_accuracy(end_time);
|
|
|
|
retval = 0;
|
|
for (;;) {
|
|
unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;
|
|
bool can_busy_loop = false;
|
|
|
|
inp = fds->in; outp = fds->out; exp = fds->ex;
|
|
rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex;
|
|
|
|
for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
|
|
unsigned long in, out, ex, all_bits, bit = 1, j;
|
|
unsigned long res_in = 0, res_out = 0, res_ex = 0;
|
|
__poll_t mask;
|
|
|
|
in = *inp++; out = *outp++; ex = *exp++;
|
|
all_bits = in | out | ex;
|
|
if (all_bits == 0) {
|
|
i += BITS_PER_LONG;
|
|
continue;
|
|
}
|
|
|
|
for (j = 0; j < BITS_PER_LONG; ++j, ++i, bit <<= 1) {
|
|
struct fd f;
|
|
if (i >= n)
|
|
break;
|
|
if (!(bit & all_bits))
|
|
continue;
|
|
mask = EPOLLNVAL;
|
|
f = fdget(i);
|
|
if (fd_file(f)) {
|
|
wait_key_set(wait, in, out, bit,
|
|
busy_flag);
|
|
mask = vfs_poll(fd_file(f), wait);
|
|
|
|
fdput(f);
|
|
}
|
|
if ((mask & POLLIN_SET) && (in & bit)) {
|
|
res_in |= bit;
|
|
retval++;
|
|
wait->_qproc = NULL;
|
|
}
|
|
if ((mask & POLLOUT_SET) && (out & bit)) {
|
|
res_out |= bit;
|
|
retval++;
|
|
wait->_qproc = NULL;
|
|
}
|
|
if ((mask & POLLEX_SET) && (ex & bit)) {
|
|
res_ex |= bit;
|
|
retval++;
|
|
wait->_qproc = NULL;
|
|
}
|
|
/* got something, stop busy polling */
|
|
if (retval) {
|
|
can_busy_loop = false;
|
|
busy_flag = 0;
|
|
|
|
/*
|
|
* only remember a returned
|
|
* POLL_BUSY_LOOP if we asked for it
|
|
*/
|
|
} else if (busy_flag & mask)
|
|
can_busy_loop = true;
|
|
|
|
}
|
|
if (res_in)
|
|
*rinp = res_in;
|
|
if (res_out)
|
|
*routp = res_out;
|
|
if (res_ex)
|
|
*rexp = res_ex;
|
|
cond_resched();
|
|
}
|
|
wait->_qproc = NULL;
|
|
if (retval || timed_out || signal_pending(current))
|
|
break;
|
|
if (table.error) {
|
|
retval = table.error;
|
|
break;
|
|
}
|
|
|
|
/* only if found POLL_BUSY_LOOP sockets && not out of time */
|
|
if (can_busy_loop && !need_resched()) {
|
|
if (!busy_start) {
|
|
busy_start = busy_loop_current_time();
|
|
continue;
|
|
}
|
|
if (!busy_loop_timeout(busy_start))
|
|
continue;
|
|
}
|
|
busy_flag = 0;
|
|
|
|
/*
|
|
* If this is the first loop and we have a timeout
|
|
* given, then we convert to ktime_t and set the to
|
|
* pointer to the expiry value.
|
|
*/
|
|
if (end_time && !to) {
|
|
expire = timespec64_to_ktime(*end_time);
|
|
to = &expire;
|
|
}
|
|
|
|
if (!poll_schedule_timeout(&table, TASK_INTERRUPTIBLE,
|
|
to, slack))
|
|
timed_out = 1;
|
|
}
|
|
|
|
poll_freewait(&table);
|
|
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* We can actually return ERESTARTSYS instead of EINTR, but I'd
|
|
* like to be certain this leads to no problems. So I return
|
|
* EINTR just for safety.
|
|
*
|
|
* Update: ERESTARTSYS breaks at least the xview clock binary, so
|
|
* I'm trying ERESTARTNOHAND which restart only when you want to.
|
|
*/
|
|
int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
|
|
fd_set __user *exp, struct timespec64 *end_time)
|
|
{
|
|
fd_set_bits fds;
|
|
void *bits;
|
|
int ret, max_fds;
|
|
size_t size, alloc_size;
|
|
struct fdtable *fdt;
|
|
/* Allocate small arguments on the stack to save memory and be faster */
|
|
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
|
|
|
|
ret = -EINVAL;
|
|
if (n < 0)
|
|
goto out_nofds;
|
|
|
|
/* max_fds can increase, so grab it once to avoid race */
|
|
rcu_read_lock();
|
|
fdt = files_fdtable(current->files);
|
|
max_fds = fdt->max_fds;
|
|
rcu_read_unlock();
|
|
if (n > max_fds)
|
|
n = max_fds;
|
|
|
|
/*
|
|
* We need 6 bitmaps (in/out/ex for both incoming and outgoing),
|
|
* since we used fdset we need to allocate memory in units of
|
|
* long-words.
|
|
*/
|
|
size = FDS_BYTES(n);
|
|
bits = stack_fds;
|
|
if (size > sizeof(stack_fds) / 6) {
|
|
/* Not enough space in on-stack array; must use kmalloc */
|
|
ret = -ENOMEM;
|
|
if (size > (SIZE_MAX / 6))
|
|
goto out_nofds;
|
|
|
|
alloc_size = 6 * size;
|
|
bits = kvmalloc(alloc_size, GFP_KERNEL);
|
|
if (!bits)
|
|
goto out_nofds;
|
|
}
|
|
fds.in = bits;
|
|
fds.out = bits + size;
|
|
fds.ex = bits + 2*size;
|
|
fds.res_in = bits + 3*size;
|
|
fds.res_out = bits + 4*size;
|
|
fds.res_ex = bits + 5*size;
|
|
|
|
if ((ret = get_fd_set(n, inp, fds.in)) ||
|
|
(ret = get_fd_set(n, outp, fds.out)) ||
|
|
(ret = get_fd_set(n, exp, fds.ex)))
|
|
goto out;
|
|
zero_fd_set(n, fds.res_in);
|
|
zero_fd_set(n, fds.res_out);
|
|
zero_fd_set(n, fds.res_ex);
|
|
|
|
ret = do_select(n, &fds, end_time);
|
|
|
|
if (ret < 0)
|
|
goto out;
|
|
if (!ret) {
|
|
ret = -ERESTARTNOHAND;
|
|
if (signal_pending(current))
|
|
goto out;
|
|
ret = 0;
|
|
}
|
|
|
|
if (set_fd_set(n, inp, fds.res_in) ||
|
|
set_fd_set(n, outp, fds.res_out) ||
|
|
set_fd_set(n, exp, fds.res_ex))
|
|
ret = -EFAULT;
|
|
|
|
out:
|
|
if (bits != stack_fds)
|
|
kvfree(bits);
|
|
out_nofds:
|
|
return ret;
|
|
}
|
|
|
|
static int kern_select(int n, fd_set __user *inp, fd_set __user *outp,
|
|
fd_set __user *exp, struct __kernel_old_timeval __user *tvp)
|
|
{
|
|
struct timespec64 end_time, *to = NULL;
|
|
struct __kernel_old_timeval tv;
|
|
int ret;
|
|
|
|
if (tvp) {
|
|
if (copy_from_user(&tv, tvp, sizeof(tv)))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to,
|
|
tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
|
|
(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = core_sys_select(n, inp, outp, exp, to);
|
|
return poll_select_finish(&end_time, tvp, PT_TIMEVAL, ret);
|
|
}
|
|
|
|
SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
|
|
fd_set __user *, exp, struct __kernel_old_timeval __user *, tvp)
|
|
{
|
|
return kern_select(n, inp, outp, exp, tvp);
|
|
}
|
|
|
|
static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
|
|
fd_set __user *exp, void __user *tsp,
|
|
const sigset_t __user *sigmask, size_t sigsetsize,
|
|
enum poll_time_type type)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
switch (type) {
|
|
case PT_TIMESPEC:
|
|
if (get_timespec64(&ts, tsp))
|
|
return -EFAULT;
|
|
break;
|
|
case PT_OLD_TIMESPEC:
|
|
if (get_old_timespec32(&ts, tsp))
|
|
return -EFAULT;
|
|
break;
|
|
default:
|
|
BUG();
|
|
}
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = core_sys_select(n, inp, outp, exp, to);
|
|
return poll_select_finish(&end_time, tsp, type, ret);
|
|
}
|
|
|
|
/*
|
|
* Most architectures can't handle 7-argument syscalls. So we provide a
|
|
* 6-argument version where the sixth argument is a pointer to a structure
|
|
* which has a pointer to the sigset_t itself followed by a size_t containing
|
|
* the sigset size.
|
|
*/
|
|
struct sigset_argpack {
|
|
sigset_t __user *p;
|
|
size_t size;
|
|
};
|
|
|
|
static inline int get_sigset_argpack(struct sigset_argpack *to,
|
|
struct sigset_argpack __user *from)
|
|
{
|
|
// the path is hot enough for overhead of copy_from_user() to matter
|
|
if (from) {
|
|
if (can_do_masked_user_access())
|
|
from = masked_user_access_begin(from);
|
|
else if (!user_read_access_begin(from, sizeof(*from)))
|
|
return -EFAULT;
|
|
unsafe_get_user(to->p, &from->p, Efault);
|
|
unsafe_get_user(to->size, &from->size, Efault);
|
|
user_read_access_end();
|
|
}
|
|
return 0;
|
|
Efault:
|
|
user_read_access_end();
|
|
return -EFAULT;
|
|
}
|
|
|
|
SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp,
|
|
fd_set __user *, exp, struct __kernel_timespec __user *, tsp,
|
|
void __user *, sig)
|
|
{
|
|
struct sigset_argpack x = {NULL, 0};
|
|
|
|
if (get_sigset_argpack(&x, sig))
|
|
return -EFAULT;
|
|
|
|
return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_TIMESPEC);
|
|
}
|
|
|
|
#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
|
|
|
|
SYSCALL_DEFINE6(pselect6_time32, int, n, fd_set __user *, inp, fd_set __user *, outp,
|
|
fd_set __user *, exp, struct old_timespec32 __user *, tsp,
|
|
void __user *, sig)
|
|
{
|
|
struct sigset_argpack x = {NULL, 0};
|
|
|
|
if (get_sigset_argpack(&x, sig))
|
|
return -EFAULT;
|
|
|
|
return do_pselect(n, inp, outp, exp, tsp, x.p, x.size, PT_OLD_TIMESPEC);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef __ARCH_WANT_SYS_OLD_SELECT
|
|
struct sel_arg_struct {
|
|
unsigned long n;
|
|
fd_set __user *inp, *outp, *exp;
|
|
struct __kernel_old_timeval __user *tvp;
|
|
};
|
|
|
|
SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
|
|
{
|
|
struct sel_arg_struct a;
|
|
|
|
if (copy_from_user(&a, arg, sizeof(a)))
|
|
return -EFAULT;
|
|
return kern_select(a.n, a.inp, a.outp, a.exp, a.tvp);
|
|
}
|
|
#endif
|
|
|
|
struct poll_list {
|
|
struct poll_list *next;
|
|
unsigned int len;
|
|
struct pollfd entries[] __counted_by(len);
|
|
};
|
|
|
|
#define POLLFD_PER_PAGE ((PAGE_SIZE-sizeof(struct poll_list)) / sizeof(struct pollfd))
|
|
|
|
/*
|
|
* Fish for pollable events on the pollfd->fd file descriptor. We're only
|
|
* interested in events matching the pollfd->events mask, and the result
|
|
* matching that mask is both recorded in pollfd->revents and returned. The
|
|
* pwait poll_table will be used by the fd-provided poll handler for waiting,
|
|
* if pwait->_qproc is non-NULL.
|
|
*/
|
|
static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
|
|
bool *can_busy_poll,
|
|
__poll_t busy_flag)
|
|
{
|
|
int fd = pollfd->fd;
|
|
__poll_t mask = 0, filter;
|
|
struct fd f;
|
|
|
|
if (fd < 0)
|
|
goto out;
|
|
mask = EPOLLNVAL;
|
|
f = fdget(fd);
|
|
if (!fd_file(f))
|
|
goto out;
|
|
|
|
/* userland u16 ->events contains POLL... bitmap */
|
|
filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
|
|
pwait->_key = filter | busy_flag;
|
|
mask = vfs_poll(fd_file(f), pwait);
|
|
if (mask & busy_flag)
|
|
*can_busy_poll = true;
|
|
mask &= filter; /* Mask out unneeded events. */
|
|
fdput(f);
|
|
|
|
out:
|
|
/* ... and so does ->revents */
|
|
pollfd->revents = mangle_poll(mask);
|
|
return mask;
|
|
}
|
|
|
|
static int do_poll(struct poll_list *list, struct poll_wqueues *wait,
|
|
struct timespec64 *end_time)
|
|
{
|
|
poll_table* pt = &wait->pt;
|
|
ktime_t expire, *to = NULL;
|
|
int timed_out = 0, count = 0;
|
|
u64 slack = 0;
|
|
__poll_t busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0;
|
|
unsigned long busy_start = 0;
|
|
|
|
/* Optimise the no-wait case */
|
|
if (end_time && !end_time->tv_sec && !end_time->tv_nsec) {
|
|
pt->_qproc = NULL;
|
|
timed_out = 1;
|
|
}
|
|
|
|
if (end_time && !timed_out)
|
|
slack = select_estimate_accuracy(end_time);
|
|
|
|
for (;;) {
|
|
struct poll_list *walk;
|
|
bool can_busy_loop = false;
|
|
|
|
for (walk = list; walk != NULL; walk = walk->next) {
|
|
struct pollfd * pfd, * pfd_end;
|
|
|
|
pfd = walk->entries;
|
|
pfd_end = pfd + walk->len;
|
|
for (; pfd != pfd_end; pfd++) {
|
|
/*
|
|
* Fish for events. If we found one, record it
|
|
* and kill poll_table->_qproc, so we don't
|
|
* needlessly register any other waiters after
|
|
* this. They'll get immediately deregistered
|
|
* when we break out and return.
|
|
*/
|
|
if (do_pollfd(pfd, pt, &can_busy_loop,
|
|
busy_flag)) {
|
|
count++;
|
|
pt->_qproc = NULL;
|
|
/* found something, stop busy polling */
|
|
busy_flag = 0;
|
|
can_busy_loop = false;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
* All waiters have already been registered, so don't provide
|
|
* a poll_table->_qproc to them on the next loop iteration.
|
|
*/
|
|
pt->_qproc = NULL;
|
|
if (!count) {
|
|
count = wait->error;
|
|
if (signal_pending(current))
|
|
count = -ERESTARTNOHAND;
|
|
}
|
|
if (count || timed_out)
|
|
break;
|
|
|
|
/* only if found POLL_BUSY_LOOP sockets && not out of time */
|
|
if (can_busy_loop && !need_resched()) {
|
|
if (!busy_start) {
|
|
busy_start = busy_loop_current_time();
|
|
continue;
|
|
}
|
|
if (!busy_loop_timeout(busy_start))
|
|
continue;
|
|
}
|
|
busy_flag = 0;
|
|
|
|
/*
|
|
* If this is the first loop and we have a timeout
|
|
* given, then we convert to ktime_t and set the to
|
|
* pointer to the expiry value.
|
|
*/
|
|
if (end_time && !to) {
|
|
expire = timespec64_to_ktime(*end_time);
|
|
to = &expire;
|
|
}
|
|
|
|
if (!poll_schedule_timeout(wait, TASK_INTERRUPTIBLE, to, slack))
|
|
timed_out = 1;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
#define N_STACK_PPS ((sizeof(stack_pps) - sizeof(struct poll_list)) / \
|
|
sizeof(struct pollfd))
|
|
|
|
static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
|
|
struct timespec64 *end_time)
|
|
{
|
|
struct poll_wqueues table;
|
|
int err = -EFAULT, fdcount;
|
|
/* Allocate small arguments on the stack to save memory and be
|
|
faster - use long to make sure the buffer is aligned properly
|
|
on 64 bit archs to avoid unaligned access */
|
|
long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
|
|
struct poll_list *const head = (struct poll_list *)stack_pps;
|
|
struct poll_list *walk = head;
|
|
unsigned int todo = nfds;
|
|
unsigned int len;
|
|
|
|
if (nfds > rlimit(RLIMIT_NOFILE))
|
|
return -EINVAL;
|
|
|
|
len = min_t(unsigned int, nfds, N_STACK_PPS);
|
|
for (;;) {
|
|
walk->next = NULL;
|
|
walk->len = len;
|
|
if (!len)
|
|
break;
|
|
|
|
if (copy_from_user(walk->entries, ufds + nfds-todo,
|
|
sizeof(struct pollfd) * walk->len))
|
|
goto out_fds;
|
|
|
|
if (walk->len >= todo)
|
|
break;
|
|
todo -= walk->len;
|
|
|
|
len = min(todo, POLLFD_PER_PAGE);
|
|
walk = walk->next = kmalloc(struct_size(walk, entries, len),
|
|
GFP_KERNEL);
|
|
if (!walk) {
|
|
err = -ENOMEM;
|
|
goto out_fds;
|
|
}
|
|
}
|
|
|
|
poll_initwait(&table);
|
|
fdcount = do_poll(head, &table, end_time);
|
|
poll_freewait(&table);
|
|
|
|
if (!user_write_access_begin(ufds, nfds * sizeof(*ufds)))
|
|
goto out_fds;
|
|
|
|
for (walk = head; walk; walk = walk->next) {
|
|
struct pollfd *fds = walk->entries;
|
|
unsigned int j;
|
|
|
|
for (j = walk->len; j; fds++, ufds++, j--)
|
|
unsafe_put_user(fds->revents, &ufds->revents, Efault);
|
|
}
|
|
user_write_access_end();
|
|
|
|
err = fdcount;
|
|
out_fds:
|
|
walk = head->next;
|
|
while (walk) {
|
|
struct poll_list *pos = walk;
|
|
walk = walk->next;
|
|
kfree(pos);
|
|
}
|
|
|
|
return err;
|
|
|
|
Efault:
|
|
user_write_access_end();
|
|
err = -EFAULT;
|
|
goto out_fds;
|
|
}
|
|
|
|
static long do_restart_poll(struct restart_block *restart_block)
|
|
{
|
|
struct pollfd __user *ufds = restart_block->poll.ufds;
|
|
int nfds = restart_block->poll.nfds;
|
|
struct timespec64 *to = NULL, end_time;
|
|
int ret;
|
|
|
|
if (restart_block->poll.has_timeout) {
|
|
end_time.tv_sec = restart_block->poll.tv_sec;
|
|
end_time.tv_nsec = restart_block->poll.tv_nsec;
|
|
to = &end_time;
|
|
}
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
|
|
if (ret == -ERESTARTNOHAND)
|
|
ret = set_restart_fn(restart_block, do_restart_poll);
|
|
|
|
return ret;
|
|
}
|
|
|
|
SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
|
|
int, timeout_msecs)
|
|
{
|
|
struct timespec64 end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (timeout_msecs >= 0) {
|
|
to = &end_time;
|
|
poll_select_set_timeout(to, timeout_msecs / MSEC_PER_SEC,
|
|
NSEC_PER_MSEC * (timeout_msecs % MSEC_PER_SEC));
|
|
}
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
|
|
if (ret == -ERESTARTNOHAND) {
|
|
struct restart_block *restart_block;
|
|
|
|
restart_block = ¤t->restart_block;
|
|
restart_block->poll.ufds = ufds;
|
|
restart_block->poll.nfds = nfds;
|
|
|
|
if (timeout_msecs >= 0) {
|
|
restart_block->poll.tv_sec = end_time.tv_sec;
|
|
restart_block->poll.tv_nsec = end_time.tv_nsec;
|
|
restart_block->poll.has_timeout = 1;
|
|
} else
|
|
restart_block->poll.has_timeout = 0;
|
|
|
|
ret = set_restart_fn(restart_block, do_restart_poll);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
|
|
struct __kernel_timespec __user *, tsp, const sigset_t __user *, sigmask,
|
|
size_t, sigsetsize)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
if (get_timespec64(&ts, tsp))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
|
|
}
|
|
|
|
#if defined(CONFIG_COMPAT_32BIT_TIME) && !defined(CONFIG_64BIT)
|
|
|
|
SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
|
|
struct old_timespec32 __user *, tsp, const sigset_t __user *, sigmask,
|
|
size_t, sigsetsize)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
if (get_old_timespec32(&ts, tsp))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
#define __COMPAT_NFDBITS (8 * sizeof(compat_ulong_t))
|
|
|
|
/*
|
|
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
|
|
* 64-bit unsigned longs.
|
|
*/
|
|
static
|
|
int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
|
|
unsigned long *fdset)
|
|
{
|
|
if (ufdset) {
|
|
return compat_get_bitmap(fdset, ufdset, nr);
|
|
} else {
|
|
zero_fd_set(nr, fdset);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static
|
|
int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
|
|
unsigned long *fdset)
|
|
{
|
|
if (!ufdset)
|
|
return 0;
|
|
return compat_put_bitmap(ufdset, fdset, nr);
|
|
}
|
|
|
|
|
|
/*
|
|
* This is a virtual copy of sys_select from fs/select.c and probably
|
|
* should be compared to it from time to time
|
|
*/
|
|
|
|
/*
|
|
* We can actually return ERESTARTSYS instead of EINTR, but I'd
|
|
* like to be certain this leads to no problems. So I return
|
|
* EINTR just for safety.
|
|
*
|
|
* Update: ERESTARTSYS breaks at least the xview clock binary, so
|
|
* I'm trying ERESTARTNOHAND which restart only when you want to.
|
|
*/
|
|
static int compat_core_sys_select(int n, compat_ulong_t __user *inp,
|
|
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
|
struct timespec64 *end_time)
|
|
{
|
|
fd_set_bits fds;
|
|
void *bits;
|
|
int size, max_fds, ret = -EINVAL;
|
|
struct fdtable *fdt;
|
|
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
|
|
|
|
if (n < 0)
|
|
goto out_nofds;
|
|
|
|
/* max_fds can increase, so grab it once to avoid race */
|
|
rcu_read_lock();
|
|
fdt = files_fdtable(current->files);
|
|
max_fds = fdt->max_fds;
|
|
rcu_read_unlock();
|
|
if (n > max_fds)
|
|
n = max_fds;
|
|
|
|
/*
|
|
* We need 6 bitmaps (in/out/ex for both incoming and outgoing),
|
|
* since we used fdset we need to allocate memory in units of
|
|
* long-words.
|
|
*/
|
|
size = FDS_BYTES(n);
|
|
bits = stack_fds;
|
|
if (size > sizeof(stack_fds) / 6) {
|
|
bits = kmalloc_array(6, size, GFP_KERNEL);
|
|
ret = -ENOMEM;
|
|
if (!bits)
|
|
goto out_nofds;
|
|
}
|
|
fds.in = (unsigned long *) bits;
|
|
fds.out = (unsigned long *) (bits + size);
|
|
fds.ex = (unsigned long *) (bits + 2*size);
|
|
fds.res_in = (unsigned long *) (bits + 3*size);
|
|
fds.res_out = (unsigned long *) (bits + 4*size);
|
|
fds.res_ex = (unsigned long *) (bits + 5*size);
|
|
|
|
if ((ret = compat_get_fd_set(n, inp, fds.in)) ||
|
|
(ret = compat_get_fd_set(n, outp, fds.out)) ||
|
|
(ret = compat_get_fd_set(n, exp, fds.ex)))
|
|
goto out;
|
|
zero_fd_set(n, fds.res_in);
|
|
zero_fd_set(n, fds.res_out);
|
|
zero_fd_set(n, fds.res_ex);
|
|
|
|
ret = do_select(n, &fds, end_time);
|
|
|
|
if (ret < 0)
|
|
goto out;
|
|
if (!ret) {
|
|
ret = -ERESTARTNOHAND;
|
|
if (signal_pending(current))
|
|
goto out;
|
|
ret = 0;
|
|
}
|
|
|
|
if (compat_set_fd_set(n, inp, fds.res_in) ||
|
|
compat_set_fd_set(n, outp, fds.res_out) ||
|
|
compat_set_fd_set(n, exp, fds.res_ex))
|
|
ret = -EFAULT;
|
|
out:
|
|
if (bits != stack_fds)
|
|
kfree(bits);
|
|
out_nofds:
|
|
return ret;
|
|
}
|
|
|
|
static int do_compat_select(int n, compat_ulong_t __user *inp,
|
|
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
|
struct old_timeval32 __user *tvp)
|
|
{
|
|
struct timespec64 end_time, *to = NULL;
|
|
struct old_timeval32 tv;
|
|
int ret;
|
|
|
|
if (tvp) {
|
|
if (copy_from_user(&tv, tvp, sizeof(tv)))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to,
|
|
tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
|
|
(tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = compat_core_sys_select(n, inp, outp, exp, to);
|
|
return poll_select_finish(&end_time, tvp, PT_OLD_TIMEVAL, ret);
|
|
}
|
|
|
|
COMPAT_SYSCALL_DEFINE5(select, int, n, compat_ulong_t __user *, inp,
|
|
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
|
|
struct old_timeval32 __user *, tvp)
|
|
{
|
|
return do_compat_select(n, inp, outp, exp, tvp);
|
|
}
|
|
|
|
struct compat_sel_arg_struct {
|
|
compat_ulong_t n;
|
|
compat_uptr_t inp;
|
|
compat_uptr_t outp;
|
|
compat_uptr_t exp;
|
|
compat_uptr_t tvp;
|
|
};
|
|
|
|
COMPAT_SYSCALL_DEFINE1(old_select, struct compat_sel_arg_struct __user *, arg)
|
|
{
|
|
struct compat_sel_arg_struct a;
|
|
|
|
if (copy_from_user(&a, arg, sizeof(a)))
|
|
return -EFAULT;
|
|
return do_compat_select(a.n, compat_ptr(a.inp), compat_ptr(a.outp),
|
|
compat_ptr(a.exp), compat_ptr(a.tvp));
|
|
}
|
|
|
|
static long do_compat_pselect(int n, compat_ulong_t __user *inp,
|
|
compat_ulong_t __user *outp, compat_ulong_t __user *exp,
|
|
void __user *tsp, compat_sigset_t __user *sigmask,
|
|
compat_size_t sigsetsize, enum poll_time_type type)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
switch (type) {
|
|
case PT_OLD_TIMESPEC:
|
|
if (get_old_timespec32(&ts, tsp))
|
|
return -EFAULT;
|
|
break;
|
|
case PT_TIMESPEC:
|
|
if (get_timespec64(&ts, tsp))
|
|
return -EFAULT;
|
|
break;
|
|
default:
|
|
BUG();
|
|
}
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_compat_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = compat_core_sys_select(n, inp, outp, exp, to);
|
|
return poll_select_finish(&end_time, tsp, type, ret);
|
|
}
|
|
|
|
struct compat_sigset_argpack {
|
|
compat_uptr_t p;
|
|
compat_size_t size;
|
|
};
|
|
static inline int get_compat_sigset_argpack(struct compat_sigset_argpack *to,
|
|
struct compat_sigset_argpack __user *from)
|
|
{
|
|
if (from) {
|
|
if (!user_read_access_begin(from, sizeof(*from)))
|
|
return -EFAULT;
|
|
unsafe_get_user(to->p, &from->p, Efault);
|
|
unsafe_get_user(to->size, &from->size, Efault);
|
|
user_read_access_end();
|
|
}
|
|
return 0;
|
|
Efault:
|
|
user_read_access_end();
|
|
return -EFAULT;
|
|
}
|
|
|
|
COMPAT_SYSCALL_DEFINE6(pselect6_time64, int, n, compat_ulong_t __user *, inp,
|
|
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
|
|
struct __kernel_timespec __user *, tsp, void __user *, sig)
|
|
{
|
|
struct compat_sigset_argpack x = {0, 0};
|
|
|
|
if (get_compat_sigset_argpack(&x, sig))
|
|
return -EFAULT;
|
|
|
|
return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
|
|
x.size, PT_TIMESPEC);
|
|
}
|
|
|
|
#if defined(CONFIG_COMPAT_32BIT_TIME)
|
|
|
|
COMPAT_SYSCALL_DEFINE6(pselect6_time32, int, n, compat_ulong_t __user *, inp,
|
|
compat_ulong_t __user *, outp, compat_ulong_t __user *, exp,
|
|
struct old_timespec32 __user *, tsp, void __user *, sig)
|
|
{
|
|
struct compat_sigset_argpack x = {0, 0};
|
|
|
|
if (get_compat_sigset_argpack(&x, sig))
|
|
return -EFAULT;
|
|
|
|
return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(x.p),
|
|
x.size, PT_OLD_TIMESPEC);
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined(CONFIG_COMPAT_32BIT_TIME)
|
|
COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
|
|
unsigned int, nfds, struct old_timespec32 __user *, tsp,
|
|
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
if (get_old_timespec32(&ts, tsp))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_compat_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
return poll_select_finish(&end_time, tsp, PT_OLD_TIMESPEC, ret);
|
|
}
|
|
#endif
|
|
|
|
/* New compat syscall for 64 bit time_t*/
|
|
COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
|
|
unsigned int, nfds, struct __kernel_timespec __user *, tsp,
|
|
const compat_sigset_t __user *, sigmask, compat_size_t, sigsetsize)
|
|
{
|
|
struct timespec64 ts, end_time, *to = NULL;
|
|
int ret;
|
|
|
|
if (tsp) {
|
|
if (get_timespec64(&ts, tsp))
|
|
return -EFAULT;
|
|
|
|
to = &end_time;
|
|
if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
|
|
return -EINVAL;
|
|
}
|
|
|
|
ret = set_compat_user_sigmask(sigmask, sigsetsize);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = do_sys_poll(ufds, nfds, to);
|
|
return poll_select_finish(&end_time, tsp, PT_TIMESPEC, ret);
|
|
}
|
|
|
|
#endif
|