From cf7683f7195689d58466ad0a2c518a1f2326c225 Mon Sep 17 00:00:00 2001 From: jiaolifeng Date: Mon, 17 Feb 2025 15:01:48 +0800 Subject: [PATCH 01/48] ANDROID: GKI: Update oplus symbol list 1 function symbol(s) added 'void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, const struct ip_options *opt)' Bug: 395723578 Change-Id: I67bf4c094f8658bc32db05a25afc0a9a8e1d7c1e Signed-off-by: jiaolifeng --- android/abi_gki_aarch64.stg | 29 +++++++++++++++++++++++++++++ android/abi_gki_aarch64_oplus | 1 + 2 files changed, 30 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index b7c163a79abb..8144b987bbbb 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -29808,6 +29808,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xd649efa3 } +pointer_reference { + id: 0x3f035b61 + kind: POINTER + pointee_type_id: 0xd64d8b1a +} pointer_reference { id: 0x3f055728 kind: POINTER @@ -33763,6 +33768,11 @@ qualified { qualifier: CONST qualified_type_id: 0x29600806 } +qualified { + id: 0xd64d8b1a + qualifier: CONST + qualified_type_id: 0x29719ae3 +} qualified { id: 0xd6640671 qualifier: CONST @@ -294859,6 +294869,15 @@ function { parameter_id: 0x6720d32f parameter_id: 0x115a10f4 } +function { + id: 0x104d46b7 + return_type_id: 0x48b5725f + parameter_id: 0x054f691a + parameter_id: 0x6720d32f + parameter_id: 0x6720d32f + parameter_id: 0xe276adef + parameter_id: 0x3f035b61 +} function { id: 0x104da524 return_type_id: 0x48b5725f @@ -343676,6 +343695,15 @@ elf_symbol { type_id: 0x9480cdfa full_name: "__i2c_transfer" } +elf_symbol { + id: 0xf9338671 + name: "__icmp_send" + is_defined: true + symbol_type: FUNCTION + crc: 0x625216d1 + type_id: 0x104d46b7 + full_name: "__icmp_send" +} elf_symbol { id: 0xf9e10bbf name: "__iio_device_register" @@ -417474,6 +417502,7 @@ interface { symbol_id: 0x09a111a4 symbol_id: 0x9ff710d8 symbol_id: 0xee9e2392 + symbol_id: 0xf9338671 symbol_id: 0xf9e10bbf symbol_id: 0x335e7054 symbol_id: 0x64c84a6a diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus index 655013a615d1..99bda1e018e6 100644 --- a/android/abi_gki_aarch64_oplus +++ b/android/abi_gki_aarch64_oplus @@ -35,6 +35,7 @@ have_governor_per_policy i2c_smbus_read_word_data i2c_smbus_write_word_data + __icmp_send iio_channel_get iio_channel_release iio_get_channel_type From 45755ee7b657de5d3d321dc6365604dbce9d850e Mon Sep 17 00:00:00 2001 From: Srinath Pandey Date: Mon, 24 Feb 2025 19:06:27 +0530 Subject: [PATCH 02/48] ANDROID: of: add export symbol for of_update_property Add export symbol for of_update_property for vendor module Bug: 390562181 Change-Id: Ieaa1074c20334cc58ebeac1a014d9aed5f7bf37a Signed-off-by: Srinath Pandey --- drivers/of/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index e1b2b9275e68..9193b13f933c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1884,6 +1884,7 @@ int of_update_property(struct device_node *np, struct property *newprop) return rc; } +EXPORT_SYMBOL_GPL(of_update_property); static void of_alias_add(struct alias_prop *ap, struct device_node *np, int id, const char *stem, int stem_len) From 6ad8aa12e174576e9a616e99b8b3c7cb4b2e94bf Mon Sep 17 00:00:00 2001 From: Srinath Pandey Date: Fri, 17 Jan 2025 16:22:32 +0530 Subject: [PATCH 03/48] ANDROID: abi_gki_aarch64_qcom: Update symbol list Symbols updated to QCOM abi symbol list for updating DT property: of_update_property Bug: 390562181 Change-Id: I1c19c4aeba3ad3a928d4d90bee06952f70dfc194 Signed-off-by: Srinath Pandey --- android/abi_gki_aarch64.stg | 10 ++++++++++ android/abi_gki_aarch64_qcom | 1 + 2 files changed, 11 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 8144b987bbbb..83ae7a429382 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -390057,6 +390057,15 @@ elf_symbol { type_id: 0x5a09df06 full_name: "of_translate_address" } +elf_symbol { + id: 0x6b89c359 + name: "of_update_property" + is_defined: true + symbol_type: FUNCTION + crc: 0xec5a0571 + type_id: 0x90903ad4 + full_name: "of_update_property" +} elf_symbol { id: 0xee187039 name: "of_usb_get_dr_mode_by_phy" @@ -422652,6 +422661,7 @@ interface { symbol_id: 0x28517749 symbol_id: 0xdfe02c28 symbol_id: 0xdcce2e99 + symbol_id: 0x6b89c359 symbol_id: 0xee187039 symbol_id: 0x7d8fe18b symbol_id: 0x02252ed7 diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index f20ef27ff873..ccd74d22f185 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -2266,6 +2266,7 @@ of_thermal_get_trip_points of_thermal_is_trip_valid of_translate_address + of_update_property on_each_cpu_cond_mask oops_in_progress open_candev From 719cffaab02b4d4709142573bba012b0e8a8bdf7 Mon Sep 17 00:00:00 2001 From: Pierre Couillaud Date: Thu, 13 Feb 2025 17:29:45 -0800 Subject: [PATCH 04/48] ANDROID: GKI: Update symbol list for BCMSTB INFO: 1 function symbol(s) added 'bool debugfs_initialized()' refs #SWANDROID-15097 Bug: 396638083 Change-Id: If9ffa6a61171199b8d87ae2a4b32a8632ba16409 Signed-off-by: Pierre Couillaud Signed-off-by: Danesh Petigara --- android/abi_gki_aarch64.stg | 10 +++++++ android/abi_gki_aarch64_bcmstb | 48 +++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 83ae7a429382..3b85d0183b1b 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -363703,6 +363703,15 @@ elf_symbol { type_id: 0x141901a7 full_name: "debugfs_file_put" } +elf_symbol { + id: 0x4931dddc + name: "debugfs_initialized" + is_defined: true + symbol_type: FUNCTION + crc: 0x716265c7 + type_id: 0xfea45b04 + full_name: "debugfs_initialized" +} elf_symbol { id: 0x5e671464 name: "debugfs_lookup" @@ -419735,6 +419744,7 @@ interface { symbol_id: 0xa80f19b8 symbol_id: 0x5f9a95c1 symbol_id: 0x01ee66df + symbol_id: 0x4931dddc symbol_id: 0x5e671464 symbol_id: 0x0d94ff56 symbol_id: 0xc28b6d25 diff --git a/android/abi_gki_aarch64_bcmstb b/android/abi_gki_aarch64_bcmstb index 1bc099ecff84..dfabff0dc590 100644 --- a/android/abi_gki_aarch64_bcmstb +++ b/android/abi_gki_aarch64_bcmstb @@ -406,6 +406,7 @@ phy_ethtool_nway_reset phy_ethtool_set_eee phy_ethtool_set_link_ksettings + phy_ethtool_set_wol phy_exit phy_init phy_init_eee @@ -801,6 +802,9 @@ # required by bcm7038_wdt.ko devm_watchdog_register_device +# required by bcm74110-rng.ko + devm_hwrng_register + # required by bcm7xxx.ko genphy_restart_aneg @@ -865,23 +869,6 @@ of_find_net_device_by_node of_find_node_by_phandle -# required by brcmstb-iommu.ko - devm_get_free_pages - generic_device_group - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unlink - iommu_device_unregister - iommu_fwspec_init - iommu_group_alloc - iommu_group_put - iommu_group_ref_get - iommu_group_set_name - pci_device_group - pci_find_host_bridge - platform_get_irq_byname - # required by brcmstb-proc-info.ko find_get_pid generic_file_open @@ -899,6 +886,21 @@ # required by brcmstb_gisb.ko __sw_hweight64 +# required by brcmstb_iommu.ko + devm_get_free_pages + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unlink + iommu_device_unregister + iommu_fwspec_init + iommu_group_alloc + iommu_group_put + iommu_group_ref_get + pci_device_group + pci_find_host_bridge + platform_get_irq_byname + # required by brcmstb_memc.ko of_match_device @@ -908,9 +910,6 @@ genphy_c37_read_status genphy_suspend -# required by btbcm.ko - efi - # required by btsdio.ko sdio_claim_host sdio_claim_irq @@ -1082,7 +1081,6 @@ phy_connect_direct phy_ethtool_ksettings_get phy_ethtool_ksettings_set - phy_ethtool_set_wol phy_get_pause phy_init_hw phy_resume @@ -1420,10 +1418,12 @@ bitmap_find_free_region bitmap_release_region devm_pci_alloc_host_bridge + devm_phy_optional_get irq_chip_ack_parent irq_domain_get_irq_data irq_domain_set_info of_pci_get_max_link_speed + of_property_read_variable_u16_array of_property_read_variable_u64_array pcie_link_speed pci_generic_config_read @@ -1447,6 +1447,12 @@ # required by phy-brcm-sata.ko of_phy_simple_xlate +# required by phy-brcm-pcie.ko + __copy_overflow + debugfs_initialized + regmap_read + strsep + # required by phy-brcm-usb-dvr.ko brcmstb_get_family_id brcmstb_get_product_id From f27efe75fc876dbb63521cd6a78cba5ba4461c5d Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Mon, 10 Feb 2025 15:21:37 +0000 Subject: [PATCH 05/48] UPSTREAM: io_uring: fix io_req_prep_async with provided buffers io_req_prep_async() can import provided buffers, commit the ring state by giving up on that before, it'll be reimported later if needed. Bug: 397153671 Reported-by: Muhammad Ramdhan Reported-by: Bing-Jhong Billy Jheng Reported-by: Jacob Soo Fixes: c7fb19428d67d ("io_uring: add support for ring mapped supplied buffers") Signed-off-by: Pavel Begunkov Signed-off-by: Greg Kroah-Hartman (cherry picked from commit a94592ec30ff67dc36c424327f1e0a9ceeeb9bd3) Signed-off-by: Lee Jones Change-Id: I0887e3efb936c793feb399d29640522215abc36b --- io_uring/io_uring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index e7e5cef535f7..a63ae4477c16 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1624,6 +1624,7 @@ bool io_alloc_async_data(struct io_kiocb *req) int io_req_prep_async(struct io_kiocb *req) { const struct io_op_def *def = &io_op_defs[req->opcode]; + int ret; /* assign early for deferred execution for non-fixed file */ if (def->needs_file && !(req->flags & REQ_F_FIXED_FILE) && !req->file) @@ -1636,7 +1637,9 @@ int io_req_prep_async(struct io_kiocb *req) if (io_alloc_async_data(req)) return -EAGAIN; } - return def->prep_async(req); + ret = def->prep_async(req); + io_kbuf_recycle(req, 0); + return ret; } static u32 io_get_sequence(struct io_kiocb *req) From 75c1d11b886013678195a91f75dd7d77880e1ac4 Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Tue, 18 Feb 2025 15:11:35 +0800 Subject: [PATCH 06/48] ANDROID: swapfile: Add EXPORT_SYMBOL_GPL for page_swap_info We present a specific requirement regarding the memory management and I/O operations.In our project,we're focused on handling scenarios where I/O delays are triggered by anoymous pages.During this period,we need to obtain swap_info_struct according to page to obtain the corresponding block device id. Bug: 397308736 Change-Id: Ibc11f412964245658cec60af42cf9486adc96e1a Signed-off-by: Marcus Ma --- mm/swapfile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/swapfile.c b/mm/swapfile.c index cbf4fb457cb7..d3c0276369d8 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3431,6 +3431,7 @@ struct swap_info_struct *page_swap_info(struct page *page) swp_entry_t entry = { .val = page_private(page) }; return swp_swap_info(entry); } +EXPORT_SYMBOL_GPL(page_swap_info); /* * out-of-line methods to avoid include hell. From 4deb2cd70382798d3b8e4fb4db7108a4ce76c30f Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Wed, 19 Feb 2025 11:15:09 +0800 Subject: [PATCH 07/48] ANDROID: Update the ABI symbol list Adding the following symbols: - page_swap_info Bug: 397308736 Change-Id: Ica1c945fd0401c0276d0409ff284fe9debc352a3 Signed-off-by: Marcus Ma --- android/abi_gki_aarch64.stg | 15 +++++++++++++++ android/abi_gki_aarch64_xiaomi | 3 +++ android/abi_gki_protected_exports_aarch64 | 7 ++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 3b85d0183b1b..4fb5194c4df6 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -307920,6 +307920,11 @@ function { parameter_id: 0xf435685e parameter_id: 0x1d19a9d5 } +function { + id: 0x3d0bcda3 + return_type_id: 0x23f6f3f6 + parameter_id: 0x06835e9c +} function { id: 0x3d0f6874 return_type_id: 0x1c3dbe5a @@ -390438,6 +390443,15 @@ elf_symbol { type_id: 0x19658c89 full_name: "page_reporting_unregister" } +elf_symbol { + id: 0xb942a21f + name: "page_swap_info" + is_defined: true + symbol_type: FUNCTION + crc: 0xb7074429 + type_id: 0x3d0bcda3 + full_name: "page_swap_info" +} elf_symbol { id: 0xb681e6bc name: "page_symlink" @@ -422712,6 +422726,7 @@ interface { symbol_id: 0x3c537500 symbol_id: 0x1b814fa6 symbol_id: 0x9ca2e070 + symbol_id: 0xb942a21f symbol_id: 0xb681e6bc symbol_id: 0x4271852e symbol_id: 0x0fe80546 diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index af5c77dcdce8..0802e4fe7141 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -485,3 +485,6 @@ __tracepoint_android_vh_get_folio_trylock_result __traceiter_android_vh_do_folio_trylock __tracepoint_android_vh_do_folio_trylock reclaim_pages + +#required by mi_iod_debug.ko +page_swap_info diff --git a/android/abi_gki_protected_exports_aarch64 b/android/abi_gki_protected_exports_aarch64 index 919bb5765e6e..c9f44faef737 100644 --- a/android/abi_gki_protected_exports_aarch64 +++ b/android/abi_gki_protected_exports_aarch64 @@ -97,7 +97,12 @@ h4_recv_buf hci_alloc_dev_priv hci_cmd_sync hci_cmd_sync_cancel +hci_cmd_sync_cancel_entry +hci_cmd_sync_dequeue +hci_cmd_sync_dequeue_once +hci_cmd_sync_lookup_entry hci_cmd_sync_queue +hci_cmd_sync_queue_once hci_cmd_sync_status hci_cmd_sync_submit hci_conn_check_secure @@ -346,4 +351,4 @@ wwan_port_txoff wwan_port_txon wwan_register_ops wwan_remove_port -wwan_unregister_ops \ No newline at end of file +wwan_unregister_ops From 9f6b96dfcaf144fb9a69b2904f9c3558a3aef0a0 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 5 Feb 2025 00:11:50 -0800 Subject: [PATCH 08/48] ANDROID: ashmem: Add support for disabling unpinning feature The final version of ashmem will not support unpinning buffers. Therefore, to be able to have the ashmem driver behave as close as possible to its final configuration for testing, add a device node that can be used to disable unpinning. This node will make it so that the ashmem shrinker stops running, and that all unpinning requests are ignored. Bug: 111903542 Change-Id: I99ae9b1a4e56ee8a5224d647a6f2f9eeeb86ef02 Signed-off-by: Isaac J. Manjarres --- drivers/staging/android/ashmem.c | 81 +++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 8e566279ce75..64772bb9c437 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -104,6 +104,9 @@ static struct kmem_cache *ashmem_range_cachep __read_mostly; */ static struct lock_class_key backing_shmem_inode_class; +/* Enable unpinning feature by default to retain compatibility with existing behavior. */ +static bool unpinning_enable = true; + static inline unsigned long range_size(struct ashmem_range *range) { return range->pgend - range->pgstart + 1; @@ -479,6 +482,9 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { unsigned long freed = 0; + if (!unpinning_enable) + return 0; + /* We might recurse into filesystem code, so bail out if necessary */ if (!(sc->gfp_mask & __GFP_FS)) return SHRINK_STOP; @@ -524,7 +530,7 @@ ashmem_shrink_count(struct shrinker *shrink, struct shrink_control *sc) * objects on the list. This means the scan function needs to return the * number of pages freed, not the number of objects scanned. */ - return lru_count; + return unpinning_enable ? lru_count : SHRINK_EMPTY; } static struct shrinker ashmem_shrinker = { @@ -802,7 +808,7 @@ static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, ret = ashmem_pin(asma, pgstart, pgend, &range); break; case ASHMEM_UNPIN: - ret = ashmem_unpin(asma, pgstart, pgend, &range); + ret = unpinning_enable ? ashmem_unpin(asma, pgstart, pgend, &range) : 0; break; case ASHMEM_GET_PIN_STATUS: ret = ashmem_get_pin_status(asma, pgstart, pgend); @@ -921,6 +927,40 @@ static void ashmem_show_fdinfo(struct seq_file *m, struct file *file) mutex_unlock(&ashmem_mutex); } #endif + +static int unpinning_enable_open(struct inode *inode, struct file *file) +{ + file->private_data = &unpinning_enable; + return 0; +} + +static ssize_t attr_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + bool *attrp = file->private_data; + char val_str[2]; + + val_str[0] = *attrp ? '1' : '0'; + val_str[1] = '\n'; + return simple_read_from_buffer(buf, count, ppos, val_str, sizeof(val_str)); +} + +static ssize_t attr_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + bool *attrp = file->private_data; + bool enable; + ssize_t ret = count; + + if (!kstrtobool_from_user(buf, count, &enable)) { + mutex_lock(&ashmem_mutex); + *attrp = enable; + mutex_unlock(&ashmem_mutex); + } else { + ret = -EINVAL; + } + + return ret; +} + static const struct file_operations ashmem_fops = { .owner = THIS_MODULE, .open = ashmem_open, @@ -946,15 +986,30 @@ int is_ashmem_file(struct file *file) } EXPORT_SYMBOL_GPL(is_ashmem_file); -static struct miscdevice ashmem_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "ashmem", - .fops = &ashmem_fops, +static const struct file_operations unpinning_enable_fops = { + .owner = THIS_MODULE, + .open = unpinning_enable_open, + .read = attr_read, + .write = attr_write, +}; + +static struct miscdevice ashmem_miscs[] = { + { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem", + .fops = &ashmem_fops, + }, + { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem_unpinning_enable", + .fops = &unpinning_enable_fops, + }, }; static int __init ashmem_init(void) { int ret = -ENOMEM; + int i; ashmem_area_cachep = kmem_cache_create("ashmem_area_cache", sizeof(struct ashmem_area), @@ -972,10 +1027,12 @@ static int __init ashmem_init(void) goto out_free1; } - ret = misc_register(&ashmem_misc); - if (ret) { - pr_err("failed to register misc device!\n"); - goto out_free2; + for (i = 0; i < ARRAY_SIZE(ashmem_miscs); i++) { + ret = misc_register(&ashmem_miscs[i]); + if (ret) { + pr_err("failed to register %s misc device!\n", ashmem_miscs[i].name); + goto out_demisc; + } } ret = register_shrinker(&ashmem_shrinker, "android-ashmem"); @@ -989,8 +1046,8 @@ static int __init ashmem_init(void) return 0; out_demisc: - misc_deregister(&ashmem_misc); -out_free2: + while (--i >= 0) + misc_deregister(&ashmem_miscs[i]); kmem_cache_destroy(ashmem_range_cachep); out_free1: kmem_cache_destroy(ashmem_area_cachep); From ef10c0ef7d6b718eb3ad0b3cee54c8fb0e4e11cc Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Fri, 14 Feb 2025 17:54:53 -0800 Subject: [PATCH 09/48] ANDROID: ashmem: Add toggle to ignore requests to deny PROT_READ mappings Memfd does not support preventing a file from being mapped with PROT_READ, as ashmem does. It would be useful to expose a knob to userspace to change ashmem's behavior to match memfd to see if any issues arise during tests. Therefore, expose a tunable that userspace can use to cause ashmem to ignore requests to deny PROT_READ mappings. Bug: 111903542 Change-Id: Id4d1770e93a4fd5a6b3be04fd82c67d0eff0200e Signed-off-by: Isaac J. Manjarres --- drivers/staging/android/ashmem.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 64772bb9c437..948baaf2c1b2 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -107,6 +107,15 @@ static struct lock_class_key backing_shmem_inode_class; /* Enable unpinning feature by default to retain compatibility with existing behavior. */ static bool unpinning_enable = true; +/* + * memfd does not allow removing permissions to map a buffer with PROT_READ. This variable + * is exposed as a tunable so that it can be used to make ashmem behave more like memfd for + * test purposes. + * + * It is set to false by default to retain compatibility with the original behavior of the driver. + */ +static bool ignore_unset_prot_read; + static inline unsigned long range_size(struct ashmem_range *range) { return range->pgend - range->pgstart + 1; @@ -549,6 +558,10 @@ static int set_prot_mask(struct ashmem_area *asma, unsigned long prot) mutex_lock(&ashmem_mutex); + /* Ensure the buffer can only be mapped with PROT_READ iff it has that permission. */ + if (ignore_unset_prot_read) + prot |= asma->prot_mask & PROT_READ; + /* the user can only remove, not add, protection bits */ if ((asma->prot_mask & prot) != prot) { ret = -EINVAL; @@ -934,6 +947,12 @@ static int unpinning_enable_open(struct inode *inode, struct file *file) return 0; } +static int ignore_unset_prot_read_open(struct inode *inode, struct file *file) +{ + file->private_data = &ignore_unset_prot_read; + return 0; +} + static ssize_t attr_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { bool *attrp = file->private_data; @@ -993,6 +1012,13 @@ static const struct file_operations unpinning_enable_fops = { .write = attr_write, }; +static const struct file_operations ignore_unset_prot_read_fops = { + .owner = THIS_MODULE, + .open = ignore_unset_prot_read_open, + .read = attr_read, + .write = attr_write, +}; + static struct miscdevice ashmem_miscs[] = { { .minor = MISC_DYNAMIC_MINOR, @@ -1004,6 +1030,11 @@ static struct miscdevice ashmem_miscs[] = { .name = "ashmem_unpinning_enable", .fops = &unpinning_enable_fops, }, + { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem_ignore_unset_prot_read", + .fops = &ignore_unset_prot_read_fops, + }, }; static int __init ashmem_init(void) From b4fef39187504f7a0b62e0d92d3d5b3e77d68339 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 18 Feb 2025 11:34:06 -0800 Subject: [PATCH 10/48] ANDROID: ashmem: Add toggle to ignore requests to deny PROT_EXEC mappings Memfd does not support preventing a file from being mapped with PROT_EXEC, as ashmem does. It would be useful to expose a knob to userspace to change ashmem's behavior to match memfd to see if any issues arise during tests. Therefore, expose a tunable that userspace can use to cause ashmem to ignore requests to deny PROT_EXEC mappings. Bug: 111903542 Change-Id: I3da63d899c4753aa704092bf8e8a2568500fa833 Signed-off-by: Isaac J. Manjarres --- drivers/staging/android/ashmem.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 948baaf2c1b2..38871d593cba 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -108,13 +108,15 @@ static struct lock_class_key backing_shmem_inode_class; static bool unpinning_enable = true; /* - * memfd does not allow removing permissions to map a buffer with PROT_READ. This variable - * is exposed as a tunable so that it can be used to make ashmem behave more like memfd for - * test purposes. + * memfd does not allow removing permissions to map a buffer with PROT_READ or PROT_EXEC. These + * variables are exposed as tunables so that they can be used to make ashmem behave more like memfd + * for test purposes. * - * It is set to false by default to retain compatibility with the original behavior of the driver. + * They are set to false by default to retain compatibility with the original behavior of the + * driver. */ static bool ignore_unset_prot_read; +static bool ignore_unset_prot_exec; static inline unsigned long range_size(struct ashmem_range *range) { @@ -562,6 +564,10 @@ static int set_prot_mask(struct ashmem_area *asma, unsigned long prot) if (ignore_unset_prot_read) prot |= asma->prot_mask & PROT_READ; + /* Ensure the buffer can only be mapped with PROT_EXEC iff it has that permission. */ + if (ignore_unset_prot_exec) + prot |= asma->prot_mask & PROT_EXEC; + /* the user can only remove, not add, protection bits */ if ((asma->prot_mask & prot) != prot) { ret = -EINVAL; @@ -953,6 +959,12 @@ static int ignore_unset_prot_read_open(struct inode *inode, struct file *file) return 0; } +static int ignore_unset_prot_exec_open(struct inode *inode, struct file *file) +{ + file->private_data = &ignore_unset_prot_exec; + return 0; +} + static ssize_t attr_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { bool *attrp = file->private_data; @@ -1019,6 +1031,13 @@ static const struct file_operations ignore_unset_prot_read_fops = { .write = attr_write, }; +static const struct file_operations ignore_unset_prot_exec_fops = { + .owner = THIS_MODULE, + .open = ignore_unset_prot_exec_open, + .read= attr_read, + .write = attr_write, +}; + static struct miscdevice ashmem_miscs[] = { { .minor = MISC_DYNAMIC_MINOR, @@ -1035,6 +1054,11 @@ static struct miscdevice ashmem_miscs[] = { .name = "ashmem_ignore_unset_prot_read", .fops = &ignore_unset_prot_read_fops, }, + { + .minor = MISC_DYNAMIC_MINOR, + .name = "ashmem_ignore_unset_prot_exec", + .fops = &ignore_unset_prot_exec_fops, + }, }; static int __init ashmem_init(void) From 004c31328abf13b1dbcdda8f56b65b0eb528487e Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 28 Jan 2025 14:44:53 -0800 Subject: [PATCH 11/48] ANDROID: mm/memfd-ashmem-shim: Introduce shim layer Certain applications treat any shared memory buffer that they obtain as an ashmem buffer, meaning that they will attempt to invoke ashmem ioctl commands on that buffer. Android is transitioning to replacing ashmem with memfd, and memfd currently does not support ashmem ioctl commands. So, when an application attempts to invoke an ashmem ioctl command on a memfd, the invocation will fail and report an error back to the app. In order to preserve compatibility between these apps and memfds, add a shim layer which will handle ashmem ioctl commands for memfds. Bug: 111903542 Change-Id: I268a29ee2805739550d79fd2c21d3cfb5a852642 Signed-off-by: Isaac J. Manjarres --- mm/Kconfig | 11 ++ mm/Makefile | 1 + mm/memfd-ashmem-shim-internal.h | 52 +++++++ mm/memfd-ashmem-shim.c | 238 ++++++++++++++++++++++++++++++++ mm/memfd-ashmem-shim.h | 21 +++ 5 files changed, 323 insertions(+) create mode 100644 mm/memfd-ashmem-shim-internal.h create mode 100644 mm/memfd-ashmem-shim.c create mode 100644 mm/memfd-ashmem-shim.h diff --git a/mm/Kconfig b/mm/Kconfig index e6178c40edc1..e6490e46c7b4 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1131,6 +1131,17 @@ config IO_MAPPING config ARCH_HAS_IOREMAP_PHYS_HOOKS bool +config MEMFD_ASHMEM_SHIM + bool "Memfd ashmem ioctl compatibility support" + depends on MEMFD_CREATE + help + This provides compatibility support for ashmem ioctl commands against + memfd file descriptors. This is useful for compatibility on Android + for older applications that may use ashmem's ioctl commands on the + now memfds passed to them. + + Unless you are running Android, say N. + config SECRETMEM def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED diff --git a/mm/Makefile b/mm/Makefile index 9e6600740b80..90c49f79de52 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -134,6 +134,7 @@ obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o obj-$(CONFIG_ZONE_DEVICE) += memremap.o obj-$(CONFIG_HMM_MIRROR) += hmm.o obj-$(CONFIG_MEMFD_CREATE) += memfd.o +obj-$(CONFIG_MEMFD_ASHMEM_SHIM) += memfd-ashmem-shim.o obj-$(CONFIG_MAPPING_DIRTY_HELPERS) += mapping_dirty_helpers.o obj-$(CONFIG_PTDUMP_CORE) += ptdump.o obj-$(CONFIG_PAGE_REPORTING) += page_reporting.o diff --git a/mm/memfd-ashmem-shim-internal.h b/mm/memfd-ashmem-shim-internal.h new file mode 100644 index 000000000000..b499434a94c7 --- /dev/null +++ b/mm/memfd-ashmem-shim-internal.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Ashmem compatability for memfd + * + * Copyright (c) 2025, Google LLC. + * Author: Isaac J. Manjarres + */ + +#ifndef _MM_MEMFD_ASHMEM_SHIM_INTERNAL_H +#define _MM_MEMFD_ASHMEM_SHIM_INTERNAL_H + +#include +#include +#include + +#define ASHMEM_NAME_LEN 256 + +/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ +#define ASHMEM_NOT_PURGED 0 +#define ASHMEM_WAS_PURGED 1 + +/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */ +#define ASHMEM_IS_UNPINNED 0 +#define ASHMEM_IS_PINNED 1 + +struct ashmem_pin { + __u32 offset; /* offset into region, in bytes, page-aligned */ + __u32 len; /* length forward from offset, in bytes, page-aligned */ +}; + +#define __ASHMEMIOC 0x77 + +#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) +#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) +#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) +#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) +#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) +#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) +#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin) +#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) +#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) +#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) +#define ASHMEM_GET_FILE_ID _IOR(__ASHMEMIOC, 11, unsigned long) + +/* support of 32bit userspace on 64bit platforms */ +#ifdef CONFIG_COMPAT +#define COMPAT_ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, compat_size_t) +#define COMPAT_ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned int) +#endif + +#endif /* _MM_MEMFD_ASHMEM_SHIM_INTERNAL_H */ diff --git a/mm/memfd-ashmem-shim.c b/mm/memfd-ashmem-shim.c new file mode 100644 index 000000000000..8c7016b905d6 --- /dev/null +++ b/mm/memfd-ashmem-shim.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Ashmem compatability for memfd + * + * Copyright (c) 2025, Google LLC. + * Author: Isaac J. Manjarres + */ + +#include +#include +#include +#include +#include + +#include "memfd-ashmem-shim.h" +#include "memfd-ashmem-shim-internal.h" + +/* file_path() returns the path of the file including the root, hence the additional "/". */ +#define MEMFD_PATH_PREFIX_LEN strlen("/memfd:") + +/* All memfd files are unlinked, and are therefore suffixed with the " (deleted)" string. */ +#define UNLINKED_FILE_SUFFIX_LEN strlen(" (deleted)") + +/* + * 1 character for the start of the path (/), NAME_MAX for the maximum length of a full memfd file + * name, UNLINKED_FILE_SUFFIX_LEN for the " (deleted)" suffix, and 1 for the NUL terminating + * character. + */ +#define MAX_FILE_PATH_SIZE (1 + NAME_MAX + UNLINKED_FILE_SUFFIX_LEN + 1) + +static char *get_memfd_file_name(struct file *file, char *buf, size_t size) +{ + char *name_end; + char *path = file_path(file, buf, size); + + if (IS_ERR(path)) + return path; + + /* Only handle memfds; we cannot make assumptions about other file names. */ + name_end = strstr(path, " (deleted)"); + if ((strstr(path, "/memfd:") != path) || !name_end) + return ERR_PTR(-EINVAL); + + /* + * Since file_path() returns the full path of the file, including the root, the format will + * be: + * + * "/memfd:testbuf (deleted)" + * + * But the ASHMEM_GET_NAME ioctl only returns the name of the buffer without any prefixes + * or suffixes. So, terminate the string at the start of the " (deleted)" suffix so that + * strlen() can be used on it from the start of the name. + */ + *name_end = '\0'; + + /* return a pointer to the start of the name */ + return &path[MEMFD_PATH_PREFIX_LEN]; +} + +static long get_name(struct file *file, void __user *name) +{ + char buf[MAX_FILE_PATH_SIZE]; + char *file_name = get_memfd_file_name(file, buf, sizeof(buf)); + size_t len; + + if (IS_ERR(file_name)) + return PTR_ERR(file_name); + + /* + * The expectation is that the user provided buffer is ASHMEM_NAME_LEN in size, which is + * larger than the maximum size of a name for a memfd buffer, so the name should always fit + * within the given buffer. + * + * However, we should ensure that the string will indeed fit in the user provided buffer. + * + * Add 1 to the copy size to account for the NUL terminator + */ + len = strlen(file_name) + 1; + if (len > ASHMEM_NAME_LEN) + return -EINVAL; + + return copy_to_user(name, file_name, len) ? -EFAULT : 0; +} + +static long get_prot_mask(struct file *file) +{ + long prot_mask = PROT_READ | PROT_EXEC; + long seals = memfd_fcntl(file, F_GET_SEALS, 0); + + if (seals < 0) + return seals; + + /* memfds are readable and executable by default. Only writability can be changed. */ + if (!(seals & (F_SEAL_WRITE | F_SEAL_FUTURE_WRITE))) + prot_mask |= PROT_WRITE; + + return prot_mask; +} + +static long set_prot_mask(struct file *file, unsigned long prot) +{ + long curr_prot = get_prot_mask(file); + long ret = 0; + + if (curr_prot < 0) + return curr_prot; + + /* + * memfds are always readable and executable; there is no way to remove either mapping + * permission, nor is there a known usecase that requires it. + * + * Attempting to remove either of these mapping permissions will return successfully, but + * will be a nop, as the buffer will still be mappable with these permissions. + */ + prot |= PROT_READ | PROT_EXEC; + + /* Only allow permissions to be removed. */ + if ((curr_prot & prot) != prot) + return -EINVAL; + + /* + * Removing PROT_WRITE: + * + * We could prevent any other mappings from having write permissions by adding the + * F_SEAL_WRITE mapping. However, that would conflict with known usecases where it is + * desirable to maintain an existing writable mapping, but forbid future writable mappings. + * + * To support those usecases, we use F_SEAL_FUTURE_WRITE. + */ + if (!(prot & PROT_WRITE)) + ret = memfd_fcntl(file, F_ADD_SEALS, F_SEAL_FUTURE_WRITE); + + return ret; +} + +/* + * memfd_ashmem_shim_ioctl - ioctl handler for ashmem commands + * @file: The shmem file. + * @cmd: The ioctl command. + * @arg: The argument for the ioctl command. + * + * The purpose of this handler is to allow old applications to continue working + * on newer kernels by allowing them to invoke ashmem ioctl commands on memfds. + * + * The ioctl handler attempts to retain as much compatibility with the ashmem + * driver as possible. + */ +long memfd_ashmem_shim_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = -ENOTTY; + unsigned long inode_nr; + + switch (cmd) { + /* + * Older applications won't create memfds and try to use ASHMEM_SET_NAME/ASHMEM_SET_SIZE on + * them intentionally. + * + * Instead, we can end up in this scenario if an old application receives a memfd that was + * created by another process. + * + * However, the current process shouldn't expect to be able to reliably [re]name/size a + * buffer that was shared with it, since the process that shared that buffer with it, or + * any other process that references the buffer could have already mapped it. + * + * Additionally in the case of ASHMEM_SET_SIZE, when processes create memfds that are going + * to be shared with other processes in Android, they also specify the size of the memory + * region and seal the file against any size changes. Therefore, ASHMEM_SET_SIZE should not + * be supported anyway. + * + * Therefore, it is reasonable to return -EINVAL here, as if the buffer was already mapped. + */ + case ASHMEM_SET_NAME: + case ASHMEM_SET_SIZE: + ret = -EINVAL; + break; + case ASHMEM_GET_NAME: + ret = get_name(file, (void __user *)arg); + break; + case ASHMEM_GET_SIZE: + ret = i_size_read(file_inode(file)); + break; + case ASHMEM_SET_PROT_MASK: + ret = set_prot_mask(file, arg); + break; + case ASHMEM_GET_PROT_MASK: + ret = get_prot_mask(file); + break; + /* + * Unpinning ashmem buffers was deprecated with the release of Android 10, + * as it did not yield any remarkable benefits. Therefore, ignore pinning + * related requests. + * + * This makes it so that memory is always "pinned" or never entirely freed + * until all references to the ashmem buffer are dropped. The memory occupied + * by the buffer is still subject to being reclaimed (swapped out) under memory + * pressure, but that is not the same as being freed. + * + * This makes it so that: + * + * 1. Memory is always pinned and therefore never purged. + * 2. Requests to unpin memory (make it a candidate for being freed) are ignored. + */ + case ASHMEM_PIN: + ret = ASHMEM_NOT_PURGED; + break; + case ASHMEM_UNPIN: + ret = 0; + break; + case ASHMEM_GET_PIN_STATUS: + ret = ASHMEM_IS_PINNED; + break; + case ASHMEM_PURGE_ALL_CACHES: + ret = capable(CAP_SYS_ADMIN) ? 0 : -EPERM; + break; + case ASHMEM_GET_FILE_ID: + inode_nr = file_inode(file)->i_ino; + if (copy_to_user((void __user *)arg, &inode_nr, sizeof(inode_nr))) + ret = -EFAULT; + else + ret = 0; + break; + } + + return ret; +} + +#ifdef CONFIG_COMPAT +long memfd_ashmem_shim_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + if (cmd == COMPAT_ASHMEM_SET_SIZE) + cmd = ASHMEM_SET_SIZE; + else if (cmd == COMPAT_ASHMEM_SET_PROT_MASK) + cmd = ASHMEM_SET_PROT_MASK; + + return memfd_ashmem_shim_ioctl(file, cmd, arg); +} +#endif diff --git a/mm/memfd-ashmem-shim.h b/mm/memfd-ashmem-shim.h new file mode 100644 index 000000000000..026789b0344b --- /dev/null +++ b/mm/memfd-ashmem-shim.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __MM_MEMFD_ASHMEM_SHIM_H +#define __MM_MEMFD_ASHMEM_SHIM_H + +/* + * mm/memfd-ashmem-shim.h + * + * Ashmem compatability for memfd + * + * Copyright (c) 2025, Google LLC. + * Author: Isaac J. Manjarres + * + */ + +#include + +long memfd_ashmem_shim_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_COMPAT +long memfd_ashmem_shim_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +#endif +#endif /* __MM_MEMFD_ASHMEM_SHIM_H */ From 6355ece3ca029e12de23cde4eb9359015069c23a Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 28 Jan 2025 14:59:07 -0800 Subject: [PATCH 12/48] ANDROID: mm: shmem: Use memfd-ashmem-shim ioctl handler Allow the memfd-ashmem-shim ioctl handler to run for any shmem file, so that memfds can handle ashmem ioctl commands. While this allows ashmem ioctl commands to be invoked on more than just memfds, this should be fine, since the ioctl commands don't expose any additional functionality than what is already achievable via other system calls. Bug: 111903542 Change-Id: I0bf57ac5a90dba66e5c2c32beff70bcf9d26db6b Signed-off-by: Isaac J. Manjarres --- mm/shmem.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/shmem.c b/mm/shmem.c index ee9642e7b3e1..a970eecb7326 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -89,6 +89,10 @@ static struct vfsmount *shm_mnt; #include "internal.h" +#ifdef CONFIG_MEMFD_ASHMEM_SHIM +#include "memfd-ashmem-shim.h" +#endif + #define BLOCKS_PER_PAGE (PAGE_SIZE/512) #define VM_ACCT(size) (PAGE_ALIGN(size) >> PAGE_SHIFT) @@ -3976,6 +3980,12 @@ static const struct file_operations shmem_file_operations = { .splice_write = iter_file_splice_write, .fallocate = shmem_fallocate, #endif +#ifdef CONFIG_MEMFD_ASHMEM_SHIM + .unlocked_ioctl = memfd_ashmem_shim_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = memfd_ashmem_shim_compat_ioctl, +#endif +#endif }; static const struct inode_operations shmem_inode_operations = { From fa3cc11118de1205fea828af1c754a76c711096b Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 5 Feb 2025 00:41:17 -0800 Subject: [PATCH 13/48] ANDROID: GKI: Enable CONFIG_MEMFD_ASHMEM_SHIM Enable memfd-ashmem compatibility support. Bug: 111903542 Change-Id: Ia4685272b2f64db737697a3e3c1640d110060111 Signed-off-by: Isaac J. Manjarres --- arch/arm64/configs/gki_defconfig | 1 + arch/x86/configs/gki_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 99fe0c1c0815..a91c46394533 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -129,6 +129,7 @@ CONFIG_CMA_DEBUGFS=y CONFIG_CMA_AREAS=32 # CONFIG_ZONE_DMA is not set CONFIG_ZONE_DEVICE=y +CONFIG_MEMFD_ASHMEM_SHIM=y CONFIG_ANON_VMA_NAME=y CONFIG_USERFAULTFD=y CONFIG_LRU_GEN=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 801559e4527c..1ba04adb3f0c 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -119,6 +119,7 @@ CONFIG_CMA_DEBUGFS=y CONFIG_CMA_AREAS=16 # CONFIG_ZONE_DMA is not set CONFIG_ZONE_DEVICE=y +CONFIG_MEMFD_ASHMEM_SHIM=y CONFIG_ANON_VMA_NAME=y CONFIG_USERFAULTFD=y CONFIG_LRU_GEN=y From eaffa3e34155d13c4a2df6d44e46d8a046c2ea4c Mon Sep 17 00:00:00 2001 From: zhanghui Date: Fri, 14 Feb 2025 16:23:03 +0800 Subject: [PATCH 14/48] ANDROID: mm: add a new vendor hook in filemap_map_pages In the current vendor hook, if next_uptodate_folio returns NULL, the first_pgoff is set to zero, and the last_pgoff is set to start_pgoff. Therefore, the collection range is from 0 to the start_pgoff. |-----------|------------|-------------|------------------| 0 start_pgoff first_pgoff last_pgoff end_pgoff We want to collect the first_pgoff to last_pgoff, so we have to add a new vendor hook. Bug: 398130226 Change-Id: I19d54c601e2ffc5de5ec2dafcd43fbdcdc84b0d2 Signed-off-by: zhanghui --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/mm.h | 4 ++++ mm/filemap.c | 3 +++ 3 files changed, 8 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 27a420dce9a5..bddbde83c145 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -472,3 +472,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_attach_sd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sdhci_get_cd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_trigger_vendor_lmk_kill); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_map_pages_range); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 4f7bfc8bcb20..74b76878fe9d 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -298,6 +298,10 @@ DECLARE_HOOK(android_vh_alloc_flags_cma_adjust, DECLARE_HOOK(android_vh_rmqueue_cma_fallback, TP_PROTO(struct zone *zone, unsigned int order, struct page **page), TP_ARGS(zone, order, page)); +DECLARE_HOOK(android_vh_filemap_map_pages_range, + TP_PROTO(struct file *file, pgoff_t orig_start_pgoff, + pgoff_t last_pgoff, vm_fault_t ret), + TP_ARGS(file, orig_start_pgoff, last_pgoff, ret)); #endif /* _TRACE_HOOK_MM_H */ /* This part must be outside protection */ diff --git a/mm/filemap.c b/mm/filemap.c index 166889921dd7..2c7ee688aa20 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3468,12 +3468,14 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, unsigned int mmap_miss = READ_ONCE(file->f_ra.mmap_miss); vm_fault_t ret = 0; pgoff_t first_pgoff = 0; + pgoff_t orig_start_pgoff = start_pgoff; rcu_read_lock(); folio = first_map_page(mapping, &xas, end_pgoff); if (!folio) goto out; first_pgoff = xas.xa_index; + orig_start_pgoff = xas.xa_index; if (filemap_map_pmd(vmf, &folio->page)) { ret = VM_FAULT_NOPAGE; @@ -3530,6 +3532,7 @@ out: rcu_read_unlock(); WRITE_ONCE(file->f_ra.mmap_miss, mmap_miss); trace_android_vh_filemap_map_pages(file, first_pgoff, last_pgoff, ret); + trace_android_vh_filemap_map_pages_range(file, orig_start_pgoff, last_pgoff, ret); return ret; } From 6b227a1f7460a974e6d66e563b452008408ddd72 Mon Sep 17 00:00:00 2001 From: zhanghui Date: Thu, 20 Feb 2025 10:42:46 +0800 Subject: [PATCH 15/48] ANDROID: GKI: Update symbol list for xiaomi 1 function symbol(s) added 'int __traceiter_android_vh_filemap_map_pages_range(void*, struct file*, unsigned long, unsigned long, vm_fault_t)' 1 variable symbol(s) added 'struct tracepoint __tracepoint_android_vh_filemap_map_pages_range' Bug: 398130226 Change-Id: I789a16f5d0bc3d11b9518c548276b2ce19514ead Signed-off-by: zhanghui --- android/abi_gki_aarch64.stg | 20 ++++++++++++++++++++ android/abi_gki_aarch64_xiaomi | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 4fb5194c4df6..5c5ff2dd7365 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -347868,6 +347868,15 @@ elf_symbol { type_id: 0x9bc01a31 full_name: "__traceiter_android_vh_filemap_map_pages" } +elf_symbol { + id: 0x4eda1196 + name: "__traceiter_android_vh_filemap_map_pages_range" + is_defined: true + symbol_type: FUNCTION + crc: 0x8911a474 + type_id: 0x9bc01a31 + full_name: "__traceiter_android_vh_filemap_map_pages_range" +} elf_symbol { id: 0x158bf9d3 name: "__traceiter_android_vh_filemap_read" @@ -352890,6 +352899,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_vh_filemap_map_pages" } +elf_symbol { + id: 0x223c9b64 + name: "__tracepoint_android_vh_filemap_map_pages_range" + is_defined: true + symbol_type: OBJECT + crc: 0xc4246b92 + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_vh_filemap_map_pages_range" +} elf_symbol { id: 0xf61927fd name: "__tracepoint_android_vh_filemap_read" @@ -417997,6 +418015,7 @@ interface { symbol_id: 0x93a4717b symbol_id: 0x49c69e22 symbol_id: 0xb7d91f76 + symbol_id: 0x4eda1196 symbol_id: 0x158bf9d3 symbol_id: 0x1fca37bf symbol_id: 0xe6702595 @@ -418555,6 +418574,7 @@ interface { symbol_id: 0x50a83025 symbol_id: 0x6d970e8c symbol_id: 0xb34d9200 + symbol_id: 0x223c9b64 symbol_id: 0xf61927fd symbol_id: 0xa3ede5d5 symbol_id: 0x539bf337 diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index 0802e4fe7141..91ed87277a20 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -488,3 +488,9 @@ reclaim_pages #required by mi_iod_debug.ko page_swap_info + +# required by launch_boost driver +__traceiter_android_vh_filemap_read +__tracepoint_android_vh_filemap_read +__traceiter_android_vh_filemap_map_pages_range +__tracepoint_android_vh_filemap_map_pages_range From 471a10d3af3b5ae239c87f1357de2d1919e7a6c6 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Fri, 28 Feb 2025 10:40:40 -0800 Subject: [PATCH 16/48] ANDROID: mm/memfd-ashmem-shim: Fix variable length array usage The size of the buffer used to retrieve the memfd file name is currently calculated at runtime, making the buffer a variable length array. However, all of the terms used in the buffer size calculation are known at compile time, so use compile time constants for the calculation. Bug: 399839316 Change-Id: Ie1edf9a28f735ebeffab07f64efc4de45f1f095a Signed-off-by: Isaac J. Manjarres --- mm/memfd-ashmem-shim.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm/memfd-ashmem-shim.c b/mm/memfd-ashmem-shim.c index 8c7016b905d6..e09d95a8b274 100644 --- a/mm/memfd-ashmem-shim.c +++ b/mm/memfd-ashmem-shim.c @@ -17,10 +17,12 @@ #include "memfd-ashmem-shim-internal.h" /* file_path() returns the path of the file including the root, hence the additional "/". */ -#define MEMFD_PATH_PREFIX_LEN strlen("/memfd:") +#define MEMFD_PATH_PREFIX "/memfd:" +#define MEMFD_PATH_PREFIX_LEN (sizeof(MEMFD_PATH_PREFIX) - 1) /* All memfd files are unlinked, and are therefore suffixed with the " (deleted)" string. */ -#define UNLINKED_FILE_SUFFIX_LEN strlen(" (deleted)") +#define UNLINKED_FILE_SUFFIX " (deleted)" +#define UNLINKED_FILE_SUFFIX_LEN (sizeof(UNLINKED_FILE_SUFFIX) - 1) /* * 1 character for the start of the path (/), NAME_MAX for the maximum length of a full memfd file @@ -38,8 +40,8 @@ static char *get_memfd_file_name(struct file *file, char *buf, size_t size) return path; /* Only handle memfds; we cannot make assumptions about other file names. */ - name_end = strstr(path, " (deleted)"); - if ((strstr(path, "/memfd:") != path) || !name_end) + name_end = strstr(path, UNLINKED_FILE_SUFFIX); + if ((strstr(path, MEMFD_PATH_PREFIX) != path) || !name_end) return ERR_PTR(-EINVAL); /* From 50eddb3fc9ed6c9f4c3f81df09c4a614d4dd7024 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 3 Mar 2025 22:16:21 +0000 Subject: [PATCH 17/48] FROMGIT: f2fs: set highest IO priority for checkpoint thread The checkpoint is the top priority thread which can stop all the filesystem operations. Let's make it RT priority. Bug: 390504516 Reviewed-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Link: https://lore.kernel.org/linux-f2fs-devel/20250303221730.1284822-1-jaegeuk@kernel.org/T/#u (cherry picked from commit 8a2d9f00d502e6ef68c6d52f0863856040ddd2db https: //git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git/ dev) Change-Id: Ife3b87ecff0ad4b8db805c1b15227f3afcd4fbd1 --- fs/f2fs/checkpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f7677843407b..ad1a319112c9 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -21,7 +21,7 @@ #include "iostat.h" #include -#define DEFAULT_CHECKPOINT_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) +#define DEFAULT_CHECKPOINT_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 3)) static struct kmem_cache *ino_entry_slab; struct kmem_cache *f2fs_inode_entry_slab; From 44db4837f75e09037bdef33d1b9d78100d41e2b7 Mon Sep 17 00:00:00 2001 From: John Scheible Date: Thu, 6 Mar 2025 19:17:26 -0800 Subject: [PATCH 18/48] ANDROID: Update the ABI symbol list Adding the following symbols: - blk_mq_quiesce_queue - blk_mq_unquiesce_queue - cpuset_cpus_allowed - lru_cache_disable - lru_disable_count - sbitmap_weight - __task_rq_lock Bug: 399486531 Change-Id: Id7ea92a966a894954b70eb10d3cc2db429221598 Signed-off-by: John Scheible --- android/abi_gki_aarch64.stg | 20 ++++++++++++++++++++ android/abi_gki_aarch64_pixel | 7 +++++++ 2 files changed, 27 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 5c5ff2dd7365..384d44e027ff 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -384990,6 +384990,24 @@ elf_symbol { type_id: 0x1c31d966 full_name: "lowpan_unregister_netdevice" } +elf_symbol { + id: 0x786bc3fa + name: "lru_cache_disable" + is_defined: true + symbol_type: FUNCTION + crc: 0x308165ec + type_id: 0x10985193 + full_name: "lru_cache_disable" +} +elf_symbol { + id: 0x9a75fb33 + name: "lru_disable_count" + is_defined: true + symbol_type: OBJECT + crc: 0x78e6f225 + type_id: 0x74d29cf1 + full_name: "lru_disable_count" +} elf_symbol { id: 0xf2af3ba0 name: "lru_gen_caps" @@ -422138,6 +422156,8 @@ interface { symbol_id: 0xbc74f02a symbol_id: 0x01bea327 symbol_id: 0x4f31c756 + symbol_id: 0x786bc3fa + symbol_id: 0x9a75fb33 symbol_id: 0xf2af3ba0 symbol_id: 0x7bd17841 symbol_id: 0xf4530070 diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index 4d0add3e28dd..af98388dc351 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -106,10 +106,12 @@ blk_mq_free_request blk_mq_free_tag_set blk_mq_map_queues + blk_mq_quiesce_queue blk_mq_start_request blk_mq_start_stopped_hw_queues blk_mq_stop_hw_queues blk_mq_unique_tag + blk_mq_unquiesce_queue blk_mq_update_nr_hw_queues blk_op_str blk_queue_chunk_sectors @@ -286,6 +288,7 @@ __cpu_present_mask cpupri_find_fitness cpu_scale + cpuset_cpus_allowed cpus_read_lock cpus_read_unlock cpu_subsys @@ -1359,6 +1362,8 @@ log_threaded_irq_wakeup_reason log_write_mmio loops_per_jiffy + lru_cache_disable + lru_disable_count mac_pton mas_empty_area_rev mas_find @@ -1960,6 +1965,7 @@ rtnl_trylock rtnl_unlock runqueues + sbitmap_weight sched_clock sched_feat_keys sched_setattr_nocheck @@ -2299,6 +2305,7 @@ tasklet_setup tasklet_unlock_wait __task_pid_nr_ns + __task_rq_lock task_rq_lock tcpci_get_tcpm_port tcpci_irq From 7d6124b6046c6cf388d45ebbee1651b5d7f7d968 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 26 Feb 2025 13:14:00 +1300 Subject: [PATCH 19/48] FROMGIT: BACKPORT: mm: fix kernel BUG when userfaultfd_move encounters swapcache userfaultfd_move() checks whether the PTE entry is present or a swap entry. - If the PTE entry is present, move_present_pte() handles folio migration by setting: src_folio->index = linear_page_index(dst_vma, dst_addr); - If the PTE entry is a swap entry, move_swap_pte() simply copies the PTE to the new dst_addr. This approach is incorrect because, even if the PTE is a swap entry, it can still reference a folio that remains in the swap cache. This creates a race window between steps 2 and 4. 1. add_to_swap: The folio is added to the swapcache. 2. try_to_unmap: PTEs are converted to swap entries. 3. pageout: The folio is written back. 4. Swapcache is cleared. If userfaultfd_move() occurs in the window between steps 2 and 4, after the swap PTE has been moved to the destination, accessing the destination triggers do_swap_page(), which may locate the folio in the swapcache. However, since the folio's index has not been updated to match the destination VMA, do_swap_page() will detect a mismatch. This can result in two critical issues depending on the system configuration. If KSM is disabled, both small and large folios can trigger a BUG during the add_rmap operation due to: page_pgoff(folio, page) != linear_page_index(vma, address) [ 13.336953] page: refcount:6 mapcount:1 mapping:00000000f43db19c index:0xffffaf150 pfn:0x4667c [ 13.337520] head: order:2 mapcount:1 entire_mapcount:0 nr_pages_mapped:1 pincount:0 [ 13.337716] memcg:ffff00000405f000 [ 13.337849] anon flags: 0x3fffc0000020459(locked|uptodate|dirty|owner_priv_1|head|swapbacked|node=0|zone=0|lastcpupid=0xffff) [ 13.338630] raw: 03fffc0000020459 ffff80008507b538 ffff80008507b538 ffff000006260361 [ 13.338831] raw: 0000000ffffaf150 0000000000004000 0000000600000000 ffff00000405f000 [ 13.339031] head: 03fffc0000020459 ffff80008507b538 ffff80008507b538 ffff000006260361 [ 13.339204] head: 0000000ffffaf150 0000000000004000 0000000600000000 ffff00000405f000 [ 13.339375] head: 03fffc0000000202 fffffdffc0199f01 ffffffff00000000 0000000000000001 [ 13.339546] head: 0000000000000004 0000000000000000 00000000ffffffff 0000000000000000 [ 13.339736] page dumped because: VM_BUG_ON_PAGE(page_pgoff(folio, page) != linear_page_index(vma, address)) [ 13.340190] ------------[ cut here ]------------ [ 13.340316] kernel BUG at mm/rmap.c:1380! [ 13.340683] Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP [ 13.340969] Modules linked in: [ 13.341257] CPU: 1 UID: 0 PID: 107 Comm: a.out Not tainted 6.14.0-rc3-gcf42737e247a-dirty #299 [ 13.341470] Hardware name: linux,dummy-virt (DT) [ 13.341671] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 13.341815] pc : __page_check_anon_rmap+0xa0/0xb0 [ 13.341920] lr : __page_check_anon_rmap+0xa0/0xb0 [ 13.342018] sp : ffff80008752bb20 [ 13.342093] x29: ffff80008752bb20 x28: fffffdffc0199f00 x27: 0000000000000001 [ 13.342404] x26: 0000000000000000 x25: 0000000000000001 x24: 0000000000000001 [ 13.342575] x23: 0000ffffaf0d0000 x22: 0000ffffaf0d0000 x21: fffffdffc0199f00 [ 13.342731] x20: fffffdffc0199f00 x19: ffff000006210700 x18: 00000000ffffffff [ 13.342881] x17: 6c203d2120296567 x16: 6170202c6f696c6f x15: 662866666f67705f [ 13.343033] x14: 6567617028454741 x13: 2929737365726464 x12: ffff800083728ab0 [ 13.343183] x11: ffff800082996bf8 x10: 0000000000000fd7 x9 : ffff80008011bc40 [ 13.343351] x8 : 0000000000017fe8 x7 : 00000000fffff000 x6 : ffff8000829eebf8 [ 13.343498] x5 : c0000000fffff000 x4 : 0000000000000000 x3 : 0000000000000000 [ 13.343645] x2 : 0000000000000000 x1 : ffff0000062db980 x0 : 000000000000005f [ 13.343876] Call trace: [ 13.344045] __page_check_anon_rmap+0xa0/0xb0 (P) [ 13.344234] folio_add_anon_rmap_ptes+0x22c/0x320 [ 13.344333] do_swap_page+0x1060/0x1400 [ 13.344417] __handle_mm_fault+0x61c/0xbc8 [ 13.344504] handle_mm_fault+0xd8/0x2e8 [ 13.344586] do_page_fault+0x20c/0x770 [ 13.344673] do_translation_fault+0xb4/0xf0 [ 13.344759] do_mem_abort+0x48/0xa0 [ 13.344842] el0_da+0x58/0x130 [ 13.344914] el0t_64_sync_handler+0xc4/0x138 [ 13.345002] el0t_64_sync+0x1ac/0x1b0 [ 13.345208] Code: aa1503e0 f000f801 910f6021 97ff5779 (d4210000) [ 13.345504] ---[ end trace 0000000000000000 ]--- [ 13.345715] note: a.out[107] exited with irqs disabled [ 13.345954] note: a.out[107] exited with preempt_count 2 If KSM is enabled, Peter Xu also discovered that do_swap_page() may trigger an unexpected CoW operation for small folios because ksm_might_need_to_copy() allocates a new folio when the folio index does not match linear_page_index(vma, addr). This patch also checks the swapcache when handling swap entries. If a match is found in the swapcache, it processes it similarly to a present PTE. However, there are some differences. For example, the folio is no longer exclusive because folio_try_share_anon_rmap_pte() is performed during unmapping. Furthermore, in the case of swapcache, the folio has already been unmapped, eliminating the risk of concurrent rmap walks and removing the need to acquire src_folio's anon_vma or lock. Note that for large folios, in the swapcache handling path, we directly return -EBUSY since split_folio() will return -EBUSY regardless if the folio is under writeback or unmapped. This is not an urgent issue, so a follow-up patch may address it separately. [v-songbaohua@oppo.com: minor cleanup according to Peter Xu] Link: https://lkml.kernel.org/r/20250226024411.47092-1-21cnbao@gmail.com Link: https://lkml.kernel.org/r/20250226001400.9129-1-21cnbao@gmail.com Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI") Signed-off-by: Barry Song Acked-by: Peter Xu Reviewed-by: Suren Baghdasaryan Cc: Andrea Arcangeli Cc: Al Viro Cc: Axel Rasmussen Cc: Brian Geffon Cc: Christian Brauner Cc: David Hildenbrand Cc: Hugh Dickins Cc: Jann Horn Cc: Kalesh Singh Cc: Liam R. Howlett Cc: Lokesh Gidra Cc: Matthew Wilcox (Oracle) Cc: Michal Hocko Cc: Mike Rapoport (IBM) Cc: Nicolas Geoffray Cc: Ryan Roberts Cc: Shuah Khan Cc: ZhangPeng Cc: Tangquan Zheng Cc: Signed-off-by: Andrew Morton Conflicts: 1. mm/userfaultfd.c [Removed pmd arguments being passed to move_swap_pte() to resolve conflicts - Lokesh Gidra] [Replaced swap_cache_index() with swp_offset() as the former doesn't exist - Lokesh Gidra] [Replaced folio_move_anon_rmap() with page_move_anon_rmap() as the former doesn't exist - Lokesh Gidra] Signed-off-by: Lokesh Gidra (cherry-picked from commit c50f8e6053b0503375c2975bf47f182445aebb4c https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-hotfixes-stable) Change-Id: I94caeac5bf78add4d78650929303a25d54d8a638 Bug: 401790618 --- mm/userfaultfd.c | 74 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 789b78245e9c..3462fed62dcc 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -18,6 +18,7 @@ #include #include #include "internal.h" +#include "swap.h" static __always_inline bool validate_dst_vma(struct vm_area_struct *dst_vma, unsigned long dst_end) @@ -974,15 +975,13 @@ out: return err; } -static int move_swap_pte(struct mm_struct *mm, +static int move_swap_pte(struct mm_struct *mm, struct vm_area_struct *dst_vma, unsigned long dst_addr, unsigned long src_addr, pte_t *dst_pte, pte_t *src_pte, pte_t orig_dst_pte, pte_t orig_src_pte, - spinlock_t *dst_ptl, spinlock_t *src_ptl) + spinlock_t *dst_ptl, spinlock_t *src_ptl, + struct folio *src_folio) { - if (!pte_swp_exclusive(orig_src_pte)) - return -EBUSY; - double_pt_lock(dst_ptl, src_ptl); if (!pte_same(ptep_get(src_pte), orig_src_pte) || @@ -991,6 +990,16 @@ static int move_swap_pte(struct mm_struct *mm, return -EAGAIN; } + /* + * The src_folio resides in the swapcache, requiring an update to its + * index and mapping to align with the dst_vma, where a swap-in may + * occur and hit the swapcache after moving the PTE. + */ + if (src_folio) { + page_move_anon_rmap(&src_folio->page, dst_vma); + src_folio->index = linear_page_index(dst_vma, dst_addr); + } + orig_src_pte = ptep_get_and_clear(mm, src_addr, src_pte); set_pte_at(mm, dst_addr, dst_pte, orig_src_pte); double_pt_unlock(dst_ptl, src_ptl); @@ -1037,6 +1046,7 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, __u64 mode) { swp_entry_t entry; + struct swap_info_struct *si = NULL; pte_t orig_src_pte, orig_dst_pte; pte_t src_folio_pte; spinlock_t *src_ptl, *dst_ptl; @@ -1207,6 +1217,8 @@ retry: orig_dst_pte, orig_src_pte, dst_ptl, src_ptl, src_folio); } else { + struct folio *folio = NULL; + entry = pte_to_swp_entry(orig_src_pte); if (non_swap_entry(entry)) { if (is_migration_entry(entry)) { @@ -1220,10 +1232,52 @@ retry: goto out; } - err = move_swap_pte(mm, dst_addr, src_addr, - dst_pte, src_pte, - orig_dst_pte, orig_src_pte, - dst_ptl, src_ptl); + if (!pte_swp_exclusive(orig_src_pte)) { + err = -EBUSY; + goto out; + } + + si = get_swap_device(entry); + if (unlikely(!si)) { + err = -EAGAIN; + goto out; + } + /* + * Verify the existence of the swapcache. If present, the folio's + * index and mapping must be updated even when the PTE is a swap + * entry. The anon_vma lock is not taken during this process since + * the folio has already been unmapped, and the swap entry is + * exclusive, preventing rmap walks. + * + * For large folios, return -EBUSY immediately, as split_folio() + * also returns -EBUSY when attempting to split unmapped large + * folios in the swapcache. This issue needs to be resolved + * separately to allow proper handling. + */ + if (!src_folio) + folio = filemap_get_folio(swap_address_space(entry), + swp_offset(entry)); + if (!IS_ERR_OR_NULL(folio)) { + if (folio_test_large(folio)) { + err = -EBUSY; + folio_put(folio); + goto out; + } + src_folio = folio; + src_folio_pte = orig_src_pte; + if (!folio_trylock(src_folio)) { + pte_unmap(&orig_src_pte); + pte_unmap(&orig_dst_pte); + src_pte = dst_pte = NULL; + put_swap_device(si); + si = NULL; + /* now we can block and wait */ + folio_lock(src_folio); + goto retry; + } + } + err = move_swap_pte(mm, dst_vma, dst_addr, src_addr, dst_pte, src_pte, + orig_dst_pte, orig_src_pte, dst_ptl, src_ptl, src_folio); } out: @@ -1240,6 +1294,8 @@ out: if (src_pte) pte_unmap(src_pte); mmu_notifier_invalidate_range_end(&range); + if (si) + put_swap_device(si); return err; } From af439accc7ddcdab9d1bcbbf2b71cf5374dbe9c8 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Wed, 26 Feb 2025 10:55:08 -0800 Subject: [PATCH 20/48] FROMGIT: userfaultfd: do not block on locking a large folio with raised refcount Lokesh recently raised an issue about UFFDIO_MOVE getting into a deadlock state when it goes into split_folio() with raised folio refcount. split_folio() expects the reference count to be exactly mapcount + num_pages_in_folio + 1 (see can_split_folio()) and fails with EAGAIN otherwise. If multiple processes are trying to move the same large folio, they raise the refcount (all tasks succeed in that) then one of them succeeds in locking the folio, while others will block in folio_lock() while keeping the refcount raised. The winner of this race will proceed with calling split_folio() and will fail returning EAGAIN to the caller and unlocking the folio. The next competing process will get the folio locked and will go through the same flow. In the meantime the original winner will be retried and will block in folio_lock(), getting into the queue of waiting processes only to repeat the same path. All this results in a livelock. An easy fix would be to avoid waiting for the folio lock while holding folio refcount, similar to madvise_free_huge_pmd() where folio lock is acquired before raising the folio refcount. Since we lock and take a refcount of the folio while holding the PTE lock, changing the order of these operations should not break anything. Modify move_pages_pte() to try locking the folio first and if that fails and the folio is large then return EAGAIN without touching the folio refcount. If the folio is single-page then split_folio() is not called, so we don't have this issue. Lokesh has a reproducer [1] and I verified that this change fixes the issue. [1] https://github.com/lokeshgidra/uffd_move_ioctl_deadlock [akpm@linux-foundation.org: reflow comment to 80 cols, s/end/end up/] Link: https://lkml.kernel.org/r/20250226185510.2732648-2-surenb@google.com Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI") Signed-off-by: Suren Baghdasaryan Reported-by: Lokesh Gidra Reviewed-by: Peter Xu Acked-by: Liam R. Howlett Cc: Andrea Arcangeli Cc: Barry Song <21cnbao@gmail.com> Cc: Barry Song Cc: David Hildenbrand Cc: Hugh Dickins Cc: Jann Horn Cc: Kalesh Singh Cc: Lorenzo Stoakes Cc: Matthew Wilcow (Oracle) Cc: Signed-off-by: Andrew Morton Signed-off-by: Lokesh Gidra (cherry-picked from commit 37b338eed10581784e854d4262da05c8d960c748 https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-hotfixes-stable) Change-Id: I71b307add9707ad3518a44623aea2e2ca417b95a Bug: 401790618 --- mm/userfaultfd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 3462fed62dcc..2f8dc8b61433 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1135,6 +1135,7 @@ retry: */ if (!src_folio) { struct folio *folio; + bool locked; /* * Pin the page while holding the lock to be sure the @@ -1154,12 +1155,26 @@ retry: goto out; } + locked = folio_trylock(folio); + /* + * We avoid waiting for folio lock with a raised + * refcount for large folios because extra refcounts + * will result in split_folio() failing later and + * retrying. If multiple tasks are trying to move a + * large folio we can end up livelocking. + */ + if (!locked && folio_test_large(folio)) { + spin_unlock(src_ptl); + err = -EAGAIN; + goto out; + } + folio_get(folio); src_folio = folio; src_folio_pte = orig_src_pte; spin_unlock(src_ptl); - if (!folio_trylock(src_folio)) { + if (!locked) { pte_unmap(&orig_src_pte); pte_unmap(&orig_dst_pte); src_pte = dst_pte = NULL; From 8d8d44ff91f180bccd435432c428ee4b9e05a329 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Wed, 26 Feb 2025 10:55:09 -0800 Subject: [PATCH 21/48] FROMGIT: userfaultfd: fix PTE unmapping stack-allocated PTE copies Current implementation of move_pages_pte() copies source and destination PTEs in order to detect concurrent changes to PTEs involved in the move. However these copies are also used to unmap the PTEs, which will fail if CONFIG_HIGHPTE is enabled because the copies are allocated on the stack. Fix this by using the actual PTEs which were kmap()ed. Link: https://lkml.kernel.org/r/20250226185510.2732648-3-surenb@google.com Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI") Signed-off-by: Suren Baghdasaryan Reported-by: Peter Xu Reviewed-by: Peter Xu Cc: Andrea Arcangeli Cc: Barry Song <21cnbao@gmail.com> Cc: Barry Song Cc: David Hildenbrand Cc: Hugh Dickins Cc: Jann Horn Cc: Kalesh Singh Cc: Liam R. Howlett Cc: Lokesh Gidra Cc: Lorenzo Stoakes Cc: Matthew Wilcow (Oracle) Cc: Signed-off-by: Andrew Morton Signed-off-by: Lokesh Gidra (cherry-picked from commit 927e926d72d9155fde3264459fe9bfd7b5e40d28 https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-hotfixes-stable) Change-Id: I0ee6c1b509ea7c4fa68056d6e512d4ac167c9234 Bug: 401790618 --- mm/userfaultfd.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 2f8dc8b61433..b45edacc7436 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1175,8 +1175,8 @@ retry: spin_unlock(src_ptl); if (!locked) { - pte_unmap(&orig_src_pte); - pte_unmap(&orig_dst_pte); + pte_unmap(src_pte); + pte_unmap(dst_pte); src_pte = dst_pte = NULL; /* now we can block and wait */ folio_lock(src_folio); @@ -1192,8 +1192,8 @@ retry: /* at this point we have src_folio locked */ if (folio_test_large(src_folio)) { /* split_folio() can block */ - pte_unmap(&orig_src_pte); - pte_unmap(&orig_dst_pte); + pte_unmap(src_pte); + pte_unmap(dst_pte); src_pte = dst_pte = NULL; err = split_folio(src_folio); if (err) @@ -1218,8 +1218,8 @@ retry: goto out; } if (!anon_vma_trylock_write(src_anon_vma)) { - pte_unmap(&orig_src_pte); - pte_unmap(&orig_dst_pte); + pte_unmap(src_pte); + pte_unmap(dst_pte); src_pte = dst_pte = NULL; /* now we can block and wait */ anon_vma_lock_write(src_anon_vma); @@ -1237,8 +1237,8 @@ retry: entry = pte_to_swp_entry(orig_src_pte); if (non_swap_entry(entry)) { if (is_migration_entry(entry)) { - pte_unmap(&orig_src_pte); - pte_unmap(&orig_dst_pte); + pte_unmap(src_pte); + pte_unmap(dst_pte); src_pte = dst_pte = NULL; migration_entry_wait(mm, src_pmd, src_addr); err = -EAGAIN; @@ -1281,8 +1281,8 @@ retry: src_folio = folio; src_folio_pte = orig_src_pte; if (!folio_trylock(src_folio)) { - pte_unmap(&orig_src_pte); - pte_unmap(&orig_dst_pte); + pte_unmap(src_pte); + pte_unmap(dst_pte); src_pte = dst_pte = NULL; put_swap_device(si); si = NULL; From 9bcabbda673adcfd8fbbfc2cdd2f738830ae385d Mon Sep 17 00:00:00 2001 From: Lokesh Gidra Date: Mon, 10 Mar 2025 19:17:57 +0000 Subject: [PATCH 22/48] ANDROID: userfaultfd: add MOVE ioctl mode to confirm bug-fixes Following issues were reported in the MOVE ioctl: 1. Panic when trying to move a source page which is in swap-cache [1] 2. Livelock when multiple threads try to move the same source page [2] Three patches have been upstreamed to fix these issues [3, 4, 5] MOVE ioctl was backported to ACK 6.1 and 6.6 for ART GC to use it [6]. Therefore, on these kernels in order to be able to identify in the userspace if the fixes are included, this mode is added. NOTE: UFFDIO_MOVE_MODE_CONFIRM_FIXED mode is only for 6.1 and 6.6 kernels, and will go away afterwards. [1] https://lore.kernel.org/linux-mm/20250219112519.92853-1-21cnbao@gmail.com/ [2] https://github.com/lokeshgidra/uffd_move_ioctl_deadlock [3] https://web.git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-hotfixes-stable&id=c50f8e6053b0503375c2975bf47f182445aebb4c [4] https://web.git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-hotfixes-stable&id=37b338eed10581784e854d4262da05c8d960c748 [5] https://web.git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-hotfixes-stable&id=927e926d72d9155fde3264459fe9bfd7b5e40d28 [6] b/274911254 Bug: 401790618 Change-Id: Ibd854ec7ac9ae6a2ca416767d032b6c71f1bc688 Signed-off-by: Lokesh Gidra --- fs/userfaultfd.c | 3 ++- include/uapi/linux/userfaultfd.h | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index ae4b211c2716..f36e6e018b26 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -1942,7 +1942,8 @@ static int userfaultfd_move(struct userfaultfd_ctx *ctx, return ret; if (uffdio_move.mode & ~(UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES| - UFFDIO_MOVE_MODE_DONTWAKE)) + UFFDIO_MOVE_MODE_DONTWAKE| + UFFDIO_MOVE_MODE_CONFIRM_FIXED)) return -EINVAL; if (mmget_not_zero(mm)) { diff --git a/include/uapi/linux/userfaultfd.h b/include/uapi/linux/userfaultfd.h index 2be5c8899f1f..ffdbefb3c5d5 100644 --- a/include/uapi/linux/userfaultfd.h +++ b/include/uapi/linux/userfaultfd.h @@ -325,6 +325,13 @@ struct uffdio_move { */ #define UFFDIO_MOVE_MODE_DONTWAKE ((__u64)1<<0) #define UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES ((__u64)1<<1) + /* + * To confirm if the ioctl has fixes to avoid panic when src folio is + * in swap-cache. Also, to avoid livelock when multiple threads try + * to move same src folio. It's a KMI workaround and cannot be relied + * upon by userspace. + */ +#define UFFDIO_MOVE_MODE_CONFIRM_FIXED ((__u64)1<<63) __u64 mode; /* * "move" is written by the ioctl and must be at the end: the From 69a6dfc9c3cbbdb7766ad528ede04bbea7c795a7 Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Wed, 12 Mar 2025 13:59:22 +0800 Subject: [PATCH 23/48] ANDROID: GKI: Update symbol list for mtk 7 function symbol(s) added 'int nfnetlink_subsys_register(const struct nfnetlink_subsystem*)' 'int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem*)' 'int nfnetlink_unicast(struct sk_buff*, struct net*, u32)' 'void nfnl_lock(__u8)' 'void nfnl_unlock(__u8)' 'int xt_register_matches(struct xt_match*, unsigned int)' 'void xt_unregister_matches(struct xt_match*, unsigned int)' Bug: 402616138 Change-Id: Ic3eaedb9ea04389141704e72e46e15e0936c0a78 Signed-off-by: Seiya Wang --- android/abi_gki_aarch64.stg | 370 ++++++++++++++++++++++++++++++++++++ android/abi_gki_aarch64_mtk | 7 + 2 files changed, 377 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 384d44e027ff..b1457540de81 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -17343,6 +17343,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x9ea548d2 } +pointer_reference { + id: 0x2d3a0e2d + kind: POINTER + pointee_type_id: 0x9ea8de28 +} pointer_reference { id: 0x2d3a2624 kind: POINTER @@ -17378,6 +17383,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x9ebc14d6 } +pointer_reference { + id: 0x2d3f694d + kind: POINTER + pointee_type_id: 0x9ebd43ab +} pointer_reference { id: 0x2d3f9ded kind: POINTER @@ -18153,6 +18163,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x9c24e4e1 } +pointer_reference { + id: 0x2d9968fe + kind: POINTER + pointee_type_id: 0x9c254566 +} pointer_reference { id: 0x2d9ade31 kind: POINTER @@ -25268,6 +25283,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xfea45b04 } +pointer_reference { + id: 0x353a0005 + kind: POINTER + pointee_type_id: 0xfea8e688 +} pointer_reference { id: 0x353b375a kind: POINTER @@ -26418,6 +26438,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xf7874bee } +pointer_reference { + id: 0x377303ef + kind: POINTER + pointee_type_id: 0xf78ce923 +} pointer_reference { id: 0x37765a7c kind: POINTER @@ -26753,6 +26778,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xcad9da82 } +pointer_reference { + id: 0x38271f7f + kind: POINTER + pointee_type_id: 0xcadc9b63 +} pointer_reference { id: 0x382837f5 kind: POINTER @@ -27283,6 +27313,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xcf54e4d8 } +pointer_reference { + id: 0x39465fdc + kind: POINTER + pointee_type_id: 0xcf5999ec +} pointer_reference { id: 0x39487d35 kind: POINTER @@ -29523,6 +29558,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xd3e2f5cd } +pointer_reference { + id: 0x3e719038 + kind: POINTER + pointee_type_id: 0xd386a67f +} pointer_reference { id: 0x3e75499e kind: POINTER @@ -29748,6 +29788,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xd1e2d78b } +pointer_reference { + id: 0x3ee93e67 + kind: POINTER + pointee_type_id: 0xd1e41f00 +} pointer_reference { id: 0x3eeac861 kind: POINTER @@ -33138,6 +33183,11 @@ qualified { qualifier: CONST qualified_type_id: 0x5a860f56 } +qualified { + id: 0xcadc9b63 + qualifier: CONST + qualified_type_id: 0x5b35db07 +} qualified { id: 0xcae03949 qualifier: CONST @@ -33388,6 +33438,11 @@ qualified { qualifier: CONST qualified_type_id: 0x4b22611e } +qualified { + id: 0xcf5999ec + qualifier: CONST + qualified_type_id: 0x4d21d13b +} qualified { id: 0xcf611249 qualifier: CONST @@ -33538,6 +33593,11 @@ qualified { qualifier: CONST qualified_type_id: 0x37145079 } +qualified { + id: 0xd1e41f00 + qualifier: CONST + qualified_type_id: 0x37d7ca8b +} qualified { id: 0xd1f5399e qualifier: CONST @@ -33638,6 +33698,11 @@ qualified { qualifier: CONST qualified_type_id: 0x3dacd33f } +qualified { + id: 0xd386a67f + qualifier: CONST + qualified_type_id: 0x3e5d2f74 +} qualified { id: 0xd395c0e4 qualifier: CONST @@ -35673,6 +35738,11 @@ qualified { qualifier: CONST qualified_type_id: 0xae5a9933 } +qualified { + id: 0xf78ce923 + qualifier: CONST + qualified_type_id: 0xae741204 +} qualified { id: 0xf7f069bd qualifier: CONST @@ -43484,6 +43554,12 @@ member { type_id: 0x0baa70a7 offset: 32 } +member { + id: 0x167a10b0 + name: "abort" + type_id: 0x2d3a0e2d + offset: 320 +} member { id: 0x370a3acc name: "abort" @@ -51630,6 +51706,12 @@ member { type_id: 0xdcbf4c2a offset: 64 } +member { + id: 0xfb49a6d7 + name: "attr_count" + type_id: 0xe8034002 + offset: 160 +} member { id: 0xa59eb82e name: "attr_g" @@ -59406,6 +59488,11 @@ member { type_id: 0x2d4fc86f offset: 640 } +member { + id: 0xbe233095 + name: "call" + type_id: 0x2d9968fe +} member { id: 0x797795d3 name: "call_ctx" @@ -60507,6 +60594,12 @@ member { name: "cb" type_id: 0xb0d2a582 } +member { + id: 0x53c39050 + name: "cb" + type_id: 0x39465fdc + offset: 128 +} member { id: 0x53e7b9ea name: "cb" @@ -60531,6 +60624,12 @@ member { name: "cb_attr" type_id: 0x44e665d5 } +member { + id: 0x1e62d319 + name: "cb_count" + type_id: 0xb3e7bac9 + offset: 72 +} member { id: 0xd8f42eb6 name: "cb_data" @@ -65211,6 +65310,12 @@ member { type_id: 0x299c4193 offset: 64 } +member { + id: 0xcddc96f8 + name: "commit" + type_id: 0x2d3f694d + offset: 256 +} member { id: 0xcdfc0362 name: "commit" @@ -87792,6 +87897,12 @@ member { type_id: 0x3110588d offset: 8256 } +member { + id: 0x103ee0ba + name: "extack" + type_id: 0x07dcdbe1 + offset: 256 +} member { id: 0x103ee183 name: "extack" @@ -136927,6 +137038,11 @@ member { type_id: 0x6720d32f offset: 64 } +member { + id: 0xaba09fa2 + name: "nfgen_family" + type_id: 0xb3e7bac9 +} member { id: 0x263b9a6d name: "nfl_bpg_offset" @@ -136939,6 +137055,12 @@ member { type_id: 0x7584e7da offset: 224 } +member { + id: 0x2f19098c + name: "nfmsg" + type_id: 0x377303ef + offset: 192 +} member { id: 0x9f1d838a name: "nfs" @@ -137345,6 +137467,12 @@ member { type_id: 0x3bd9eb0b offset: 64 } +member { + id: 0xda734f0b + name: "nlh" + type_id: 0x3bd9eb0b + offset: 128 +} member { id: 0x069bedc0 name: "nlhdr" @@ -153060,6 +153188,12 @@ member { type_id: 0x3a40fc42 offset: 256 } +member { + id: 0x60d35545 + name: "policy" + type_id: 0x3a40fc42 + offset: 64 +} member { id: 0x60d356d3 name: "policy" @@ -167770,6 +167904,12 @@ member { type_id: 0x33756485 offset: 192 } +member { + id: 0x01975b31 + name: "res_id" + type_id: 0x7584e7da + offset: 16 +} member { id: 0xa7655f29 name: "res_table" @@ -189312,6 +189452,12 @@ member { type_id: 0x1c5ceff7 offset: 2496 } +member { + id: 0x7f586e0a + name: "subsys_id" + type_id: 0xb3e7bac9 + offset: 64 +} member { id: 0x7f7ac96d name: "subsys_id" @@ -200459,6 +200605,12 @@ member { type_id: 0x295c7202 offset: 3208 } +member { + id: 0x5c7febb9 + name: "type" + type_id: 0x293705d2 + offset: 128 +} member { id: 0x5c839712 name: "type" @@ -205692,6 +205844,12 @@ member { name: "valid" type_id: 0x26554526 } +member { + id: 0x036a906a + name: "valid_genid" + type_id: 0x353a0005 + offset: 384 +} member { id: 0xa6274290 name: "valid_ioctls" @@ -249744,6 +249902,60 @@ struct_union { member_id: 0xd905c561 } } +struct_union { + id: 0xae741204 + kind: STRUCT + name: "nfgenmsg" + definition { + bytesize: 4 + member_id: 0xaba09fa2 + member_id: 0xa6d2d826 + member_id: 0x01975b31 + } +} +struct_union { + id: 0x5b35db07 + kind: STRUCT + name: "nfnetlink_subsystem" + definition { + bytesize: 64 + member_id: 0x0de57ce8 + member_id: 0x7f586e0a + member_id: 0x1e62d319 + member_id: 0x53c39050 + member_id: 0x4a965a99 + member_id: 0xcddc96f8 + member_id: 0x167a10b0 + member_id: 0x036a906a + member_id: 0x2d081245 + } +} +struct_union { + id: 0x4d21d13b + kind: STRUCT + name: "nfnl_callback" + definition { + bytesize: 32 + member_id: 0xbe233095 + member_id: 0x60d35545 + member_id: 0x5c7febb9 + member_id: 0xfb49a6d7 + member_id: 0x2d081dfb + } +} +struct_union { + id: 0x3e5d2f74 + kind: STRUCT + name: "nfnl_info" + definition { + bytesize: 40 + member_id: 0x7203ed5f + member_id: 0x828c8d54 + member_id: 0xda734f0b + member_id: 0x2f19098c + member_id: 0x103ee0ba + } +} struct_union { id: 0x5d26223d kind: STRUCT @@ -286817,6 +287029,46 @@ enumeration { } } } +enumeration { + id: 0x56760d43 + name: "nfnl_abort_action" + definition { + underlying_type_id: 0x4585663f + enumerator { + name: "NFNL_ABORT_NONE" + } + enumerator { + name: "NFNL_ABORT_AUTOLOAD" + value: 1 + } + enumerator { + name: "NFNL_ABORT_VALIDATE" + value: 2 + } + } +} +enumeration { + id: 0x293705d2 + name: "nfnl_callback_type" + definition { + underlying_type_id: 0x4585663f + enumerator { + name: "NFNL_CB_UNSPEC" + } + enumerator { + name: "NFNL_CB_MUTEX" + value: 1 + } + enumerator { + name: "NFNL_CB_RCU" + value: 2 + } + enumerator { + name: "NFNL_CB_BATCH" + value: 3 + } + } +} enumeration { id: 0xa28f9420 name: "nl80211_band" @@ -297798,6 +298050,12 @@ function { return_type_id: 0x48b5725f parameter_id: 0x0d5f1839 } +function { + id: 0x13d009d7 + return_type_id: 0x48b5725f + parameter_id: 0x09793771 + parameter_id: 0x4585663f +} function { id: 0x13d261bc return_type_id: 0x48b5725f @@ -307908,6 +308166,11 @@ function { return_type_id: 0x33756485 parameter_id: 0x37b4f743 } +function { + id: 0x3c61bf21 + return_type_id: 0x48b5725f + parameter_id: 0xb3e7bac9 +} function { id: 0x3c97e3d9 return_type_id: 0x33756485 @@ -317991,6 +318254,11 @@ function { parameter_id: 0x38aab014 parameter_id: 0x6720d32f } +function { + id: 0x938924f0 + return_type_id: 0x6720d32f + parameter_id: 0x38271f7f +} function { id: 0x93898074 return_type_id: 0x6720d32f @@ -330500,6 +330768,13 @@ function { parameter_id: 0x18bd6530 parameter_id: 0x6d7f5ff6 } +function { + id: 0x9c254566 + return_type_id: 0x6720d32f + parameter_id: 0x054f691a + parameter_id: 0x3e719038 + parameter_id: 0x3ee93e67 +} function { id: 0x9c2b054b return_type_id: 0x6720d32f @@ -334897,6 +335172,13 @@ function { return_type_id: 0x6720d32f parameter_id: 0x0ca27481 } +function { + id: 0x9ea8de28 + return_type_id: 0x6720d32f + parameter_id: 0x0ca27481 + parameter_id: 0x054f691a + parameter_id: 0x56760d43 +} function { id: 0x9eb16478 return_type_id: 0x6720d32f @@ -334953,6 +335235,12 @@ function { parameter_id: 0x0e6618c4 parameter_id: 0x295c7202 } +function { + id: 0x9ebd43ab + return_type_id: 0x6720d32f + parameter_id: 0x0ca27481 + parameter_id: 0x054f691a +} function { id: 0x9ebe912b return_type_id: 0x6720d32f @@ -334999,6 +335287,12 @@ function { parameter_id: 0x1bb6a471 parameter_id: 0x07dcdbe1 } +function { + id: 0x9ec8bb6b + return_type_id: 0x6720d32f + parameter_id: 0x09793771 + parameter_id: 0x4585663f +} function { id: 0x9ec960c7 return_type_id: 0x6720d32f @@ -341795,6 +342089,12 @@ function { id: 0xfea45b04 return_type_id: 0x6d7f5ff6 } +function { + id: 0xfea8e688 + return_type_id: 0x6d7f5ff6 + parameter_id: 0x0ca27481 + parameter_id: 0xc9082b19 +} function { id: 0xfebe0504 return_type_id: 0x6d7f5ff6 @@ -388271,6 +388571,51 @@ elf_symbol { type_id: 0x9cd33969 full_name: "nfc_vendor_cmd_reply" } +elf_symbol { + id: 0x676923d3 + name: "nfnetlink_subsys_register" + is_defined: true + symbol_type: FUNCTION + crc: 0x3b9a7b91 + type_id: 0x938924f0 + full_name: "nfnetlink_subsys_register" +} +elf_symbol { + id: 0xc0c6c63a + name: "nfnetlink_subsys_unregister" + is_defined: true + symbol_type: FUNCTION + crc: 0xa2987a00 + type_id: 0x938924f0 + full_name: "nfnetlink_subsys_unregister" +} +elf_symbol { + id: 0xce121652 + name: "nfnetlink_unicast" + is_defined: true + symbol_type: FUNCTION + crc: 0x61236c92 + type_id: 0x9cd3f2b1 + full_name: "nfnetlink_unicast" +} +elf_symbol { + id: 0x3c10aa1e + name: "nfnl_lock" + is_defined: true + symbol_type: FUNCTION + crc: 0x5ce3b588 + type_id: 0x3c61bf21 + full_name: "nfnl_lock" +} +elf_symbol { + id: 0x4b91041f + name: "nfnl_unlock" + is_defined: true + symbol_type: FUNCTION + crc: 0xdb065657 + type_id: 0x3c61bf21 + full_name: "nfnl_unlock" +} elf_symbol { id: 0x6aeef72a name: "nla_append" @@ -417105,6 +417450,15 @@ elf_symbol { type_id: 0x9fdeaef3 full_name: "xt_register_match" } +elf_symbol { + id: 0xa7a837dd + name: "xt_register_matches" + is_defined: true + symbol_type: FUNCTION + crc: 0xbaed6f01 + type_id: 0x9ec8bb6b + full_name: "xt_register_matches" +} elf_symbol { id: 0xb2fbe60e name: "xt_register_target" @@ -417150,6 +417504,15 @@ elf_symbol { type_id: 0x12c61c4f full_name: "xt_unregister_match" } +elf_symbol { + id: 0xa7e146e8 + name: "xt_unregister_matches" + is_defined: true + symbol_type: FUNCTION + crc: 0x58c97d7f + type_id: 0x13d009d7 + full_name: "xt_unregister_matches" +} elf_symbol { id: 0x15f1eb71 name: "xt_unregister_target" @@ -422521,6 +422884,11 @@ interface { symbol_id: 0x22e68369 symbol_id: 0xefd6be85 symbol_id: 0x53dde8dc + symbol_id: 0x676923d3 + symbol_id: 0xc0c6c63a + symbol_id: 0xce121652 + symbol_id: 0x3c10aa1e + symbol_id: 0x4b91041f symbol_id: 0x6aeef72a symbol_id: 0x915620e9 symbol_id: 0x1570bf50 @@ -425725,11 +426093,13 @@ interface { symbol_id: 0x8eb67e0f symbol_id: 0xf6d0be30 symbol_id: 0x7a3f2cd6 + symbol_id: 0xa7a837dd symbol_id: 0xb2fbe60e symbol_id: 0x450f3768 symbol_id: 0xffcb0fa2 symbol_id: 0xa2ee5f12 symbol_id: 0x807b9318 + symbol_id: 0xa7e146e8 symbol_id: 0x15f1eb71 symbol_id: 0x7c598ee8 symbol_id: 0x2407d2bf diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index d4be95cc43af..46313f2a6297 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -1720,6 +1720,11 @@ net_selftest_get_count net_selftest_get_strings nf_conntrack_destroy + nfnetlink_subsys_register + nfnetlink_subsys_unregister + nfnetlink_unicast + nfnl_lock + nfnl_unlock nf_register_net_hooks nf_unregister_net_hooks nla_find @@ -3569,6 +3574,8 @@ xsk_tx_peek_desc xsk_tx_release xsk_uses_need_wakeup + xt_register_matches + xt_unregister_matches zlib_deflate zlib_deflateEnd zlib_deflateInit2 From efd0bedd2cb21169739c47ac449ae687e11751e9 Mon Sep 17 00:00:00 2001 From: Bian Jin chen Date: Wed, 12 Mar 2025 14:59:41 +0800 Subject: [PATCH 24/48] ANDROID: GKI: Update rockchip symbols for drm driver. INFO: 4 function symbol(s) added 'bool drm_bridge_is_panel(const struct drm_bridge*)' 'int drm_panel_bridge_set_orientation(struct drm_connector*, struct drm_bridge*)' 'struct drm_bridge* drmm_of_get_bridge(struct drm_device*, struct device_node*, u32, u32)' 'struct drm_bridge* drmm_panel_bridge_add(struct drm_device*, struct drm_panel*)' Bug: 300024866 Signed-off-by: Bian Jin chen Change-Id: I256402894b3a19be401c27113c0fe52647d43531 --- android/abi_gki_aarch64.stg | 75 ++++++++++++++++++++++++++++++++ android/abi_gki_aarch64_rockchip | 4 ++ 2 files changed, 79 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index b1457540de81..0ad34dc581a2 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -25963,6 +25963,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xf0da0508 } +pointer_reference { + id: 0x36aa7537 + kind: POINTER + pointee_type_id: 0xf0e93241 +} pointer_reference { id: 0x36aab51f kind: POINTER @@ -35408,6 +35413,11 @@ qualified { qualifier: CONST qualified_type_id: 0xb1b25547 } +qualified { + id: 0xf0e93241 + qualifier: CONST + qualified_type_id: 0xb3e37f8f +} qualified { id: 0xf0f451c7 qualifier: CONST @@ -314907,6 +314917,12 @@ function { parameter_id: 0x6720d32f parameter_id: 0x914dbfdc } +function { + id: 0x9174292d + return_type_id: 0x6720d32f + parameter_id: 0x31b5a66f + parameter_id: 0x2668e644 +} function { id: 0x9175015c return_type_id: 0x6720d32f @@ -319014,6 +319030,14 @@ function { parameter_id: 0x25653b02 parameter_id: 0x396f8ae8 } +function { + id: 0x943f99cd + return_type_id: 0x2668e644 + parameter_id: 0x3b04bead + parameter_id: 0x347303b4 + parameter_id: 0xc9082b19 + parameter_id: 0xc9082b19 +} function { id: 0x94404485 return_type_id: 0x6720d32f @@ -319360,6 +319384,12 @@ function { parameter_id: 0x25ffeea5 parameter_id: 0x19671b46 } +function { + id: 0x949eb61b + return_type_id: 0x2668e644 + parameter_id: 0x3b04bead + parameter_id: 0x10617cac +} function { id: 0x949fa126 return_type_id: 0x6720d32f @@ -340977,6 +341007,11 @@ function { parameter_id: 0x34df9ab6 parameter_id: 0x26847863 } +function { + id: 0xf30ec649 + return_type_id: 0x6d7f5ff6 + parameter_id: 0x36aa7537 +} function { id: 0xf3110cae return_type_id: 0x6d7f5ff6 @@ -370202,6 +370237,15 @@ elf_symbol { type_id: 0x182b2835 full_name: "drm_bridge_hpd_notify" } +elf_symbol { + id: 0xbaf4f45d + name: "drm_bridge_is_panel" + is_defined: true + symbol_type: FUNCTION + crc: 0x3a74b7d0 + type_id: 0xf30ec649 + full_name: "drm_bridge_is_panel" +} elf_symbol { id: 0x69a31cde name: "drm_bridge_remove" @@ -372560,6 +372604,15 @@ elf_symbol { type_id: 0x19026802 full_name: "drm_panel_bridge_remove" } +elf_symbol { + id: 0x18d15528 + name: "drm_panel_bridge_set_orientation" + is_defined: true + symbol_type: FUNCTION + crc: 0x155a5428 + type_id: 0x9174292d + full_name: "drm_panel_bridge_set_orientation" +} elf_symbol { id: 0x213cfa4f name: "drm_panel_disable" @@ -373334,6 +373387,24 @@ elf_symbol { type_id: 0x9341cc84 full_name: "drmm_mode_config_init" } +elf_symbol { + id: 0x919d8551 + name: "drmm_of_get_bridge" + is_defined: true + symbol_type: FUNCTION + crc: 0x8fe251ff + type_id: 0x943f99cd + full_name: "drmm_of_get_bridge" +} +elf_symbol { + id: 0x943167de + name: "drmm_panel_bridge_add" + is_defined: true + symbol_type: FUNCTION + crc: 0x5316c3d0 + type_id: 0x949eb61b + full_name: "drmm_panel_bridge_add" +} elf_symbol { id: 0x4dae13e9 name: "drop_nlink" @@ -420843,6 +420914,7 @@ interface { symbol_id: 0x3ef0db06 symbol_id: 0xc72378aa symbol_id: 0xd82232b3 + symbol_id: 0xbaf4f45d symbol_id: 0x69a31cde symbol_id: 0xfbc28ac3 symbol_id: 0xe2f527ca @@ -421105,6 +421177,7 @@ interface { symbol_id: 0xd67ad69f symbol_id: 0x48cde8a9 symbol_id: 0x633d0644 + symbol_id: 0x18d15528 symbol_id: 0x213cfa4f symbol_id: 0xaaae7be8 symbol_id: 0x06b3c598 @@ -421191,6 +421264,8 @@ interface { symbol_id: 0xdaf34c14 symbol_id: 0x1f1ab070 symbol_id: 0x66dcfd31 + symbol_id: 0x919d8551 + symbol_id: 0x943167de symbol_id: 0x4dae13e9 symbol_id: 0x367672f6 symbol_id: 0xe2b96ffd diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 69abf52bd41b..ed1693df7d00 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -2498,6 +2498,7 @@ __drm_atomic_state_free drm_bridge_chain_mode_set drm_bridge_get_edid + drm_bridge_is_panel drm_connector_list_update drm_crtc_cleanup drm_crtc_enable_color_mgmt @@ -2543,7 +2544,9 @@ drm_kms_helper_poll_init drm_mm_init drm_mm_insert_node_in_range + drmm_of_get_bridge drmm_mode_config_init + drmm_panel_bridge_add drm_mm_print drm_mm_remove_node drm_mm_reserve_node @@ -2567,6 +2570,7 @@ drm_mode_validate_ycbcr420 drm_of_crtc_port_mask drm_of_encoder_active_endpoint + drm_panel_bridge_set_orientation drm_plane_cleanup drm_plane_create_alpha_property drm_plane_create_blend_mode_property From 70d032fba5f491b3217afe113b9ec4f19d5abdab Mon Sep 17 00:00:00 2001 From: gy niu Date: Thu, 13 Mar 2025 20:39:24 +0800 Subject: [PATCH 25/48] ANDROID: GKI: Add KMI symbol list for zebra These symbols are required to third part ethernet driver pegasus.ko and smsc95xx.ko INFO: 2 function symbol(s) added 'void mii_ethtool_get_link_ksettings(struct mii_if_info*, struct ethtool_link_ksettings*)' 'int mii_ethtool_set_link_ksettings(struct mii_if_info*, const struct ethtool_link_ksettings*)' Bug: 403203480 Change-Id: Idfb8fad289516d5cbbe6235bca6c87bd24406ca0 Signed-off-by: gy niu --- BUILD.bazel | 1 + android/abi_gki_aarch64.stg | 32 ++++++++++++++++++++++++++++++++ android/abi_gki_aarch64_zebra | 29 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 android/abi_gki_aarch64_zebra diff --git a/BUILD.bazel b/BUILD.bazel index 466f1d0e3334..d5c90df09987 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -131,6 +131,7 @@ filegroup( "android/abi_gki_aarch64_virtual_device", "android/abi_gki_aarch64_vivo", "android/abi_gki_aarch64_xiaomi", + "android/abi_gki_aarch64_zebra", ], visibility = ["//visibility:public"], ) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 0ad34dc581a2..3ddfc4d80af9 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -298538,6 +298538,12 @@ function { parameter_id: 0x1d44326e parameter_id: 0x054f691a } +function { + id: 0x147ac3d5 + return_type_id: 0x48b5725f + parameter_id: 0x12191e2a + parameter_id: 0x19357319 +} function { id: 0x147c9fd8 return_type_id: 0x48b5725f @@ -324324,6 +324330,12 @@ function { parameter_id: 0x1e870478 parameter_id: 0xf017819f } +function { + id: 0x99e350e4 + return_type_id: 0x6720d32f + parameter_id: 0x12191e2a + parameter_id: 0x397d1060 +} function { id: 0x99e386dd return_type_id: 0x6720d32f @@ -386392,6 +386404,15 @@ elf_symbol { type_id: 0xcb5a4db0 full_name: "mii_check_media" } +elf_symbol { + id: 0x399512e2 + name: "mii_ethtool_get_link_ksettings" + is_defined: true + symbol_type: FUNCTION + crc: 0x9d480e3b + type_id: 0x147ac3d5 + full_name: "mii_ethtool_get_link_ksettings" +} elf_symbol { id: 0xbc90165b name: "mii_ethtool_gset" @@ -386401,6 +386422,15 @@ elf_symbol { type_id: 0x142e3633 full_name: "mii_ethtool_gset" } +elf_symbol { + id: 0x69f7fc4b + name: "mii_ethtool_set_link_ksettings" + is_defined: true + symbol_type: FUNCTION + crc: 0x14505b9c + type_id: 0x99e350e4 + full_name: "mii_ethtool_set_link_ksettings" +} elf_symbol { id: 0x863e9436 name: "mii_link_ok" @@ -422709,7 +422739,9 @@ interface { symbol_id: 0x89c6398f symbol_id: 0xbad16ab3 symbol_id: 0x68c3a63b + symbol_id: 0x399512e2 symbol_id: 0xbc90165b + symbol_id: 0x69f7fc4b symbol_id: 0x863e9436 symbol_id: 0x1579ecd2 symbol_id: 0xe4572a81 diff --git a/android/abi_gki_aarch64_zebra b/android/abi_gki_aarch64_zebra new file mode 100644 index 000000000000..b8d74df3f44e --- /dev/null +++ b/android/abi_gki_aarch64_zebra @@ -0,0 +1,29 @@ +[abi_symbol_list] + +#required by pegasus.ko + mii_nway_restart + mii_link_ok + mii_ethtool_get_link_ksettings + mii_ethtool_set_link_ksettings + +#required by susc95xx.ko + usbnet_get_endpoints + usbnet_write_cmd + usbnet_write_cmd_nopm + usbnet_read_cmd + usbnet_read_cmd_nopm + usbnet_open + usbnet_stop + usbnet_start_xmit + usbnet_change_mtu + usbnet_tx_timeout + usbnet_write_cmd_async + usbnet_get_drvinfo + usbnet_get_msglevel + usbnet_set_msglevel + usbnet_defer_kevent + usbnet_skb_return + usbnet_probe + usbnet_disconnect + usbnet_suspend + usbnet_resume From 27895588a299b91ba1cc5c9a3995e25c1ae205ae Mon Sep 17 00:00:00 2001 From: Qi Han Date: Sun, 29 Sep 2024 02:00:10 -0600 Subject: [PATCH 26/48] BACKPORT: f2fs: compress: fix inconsistent update of i_blocks in release_compress_blocks and reserve_compress_blocks After release a file and subsequently reserve it, the FSCK flag is set when the file is deleted, as shown in the following backtrace: F2FS-fs (dm-48): Inconsistent i_blocks, ino:401231, iblocks:1448, sectors:1472 fs_rec_info_write_type+0x58/0x274 f2fs_rec_info_write+0x1c/0x2c set_sbi_flag+0x74/0x98 dec_valid_block_count+0x150/0x190 f2fs_truncate_data_blocks_range+0x2d4/0x3cc f2fs_do_truncate_blocks+0x2fc/0x5f0 f2fs_truncate_blocks+0x68/0x100 f2fs_truncate+0x80/0x128 f2fs_evict_inode+0x1a4/0x794 evict+0xd4/0x280 iput+0x238/0x284 do_unlinkat+0x1ac/0x298 __arm64_sys_unlinkat+0x48/0x68 invoke_syscall+0x58/0x11c For clusters of the following type, i_blocks are decremented by 1 and i_compr_blocks are incremented by 7 in release_compress_blocks, while updates to i_blocks and i_compr_blocks are skipped in reserve_compress_blocks. raw node: D D D D D D D D after compress: C D D D D D D D after reserve: C D D D D D D D Let's update i_blocks and i_compr_blocks properly in reserve_compress_blocks. Bug: 403145794 Fixes: eb8fbaa53374 ("f2fs: compress: fix to check unreleased compressed cluster") Change-Id: I596af62bbd54941bfc77f30e182db94e81cba59b Signed-off-by: Qi Han Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit 26413ce18e85de3dda2cd3d72c3c3e8ab8f4f996) (cherry picked from commit 90d495244f3b9d0f69f7a158d2fcbc0d91d2592e) --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 48a04475102c..e8ba98a18598 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3738,7 +3738,7 @@ static int reserve_compress_blocks(struct dnode_of_data *dn, pgoff_t count, to_reserved = cluster_size - compr_blocks - reserved; /* for the case all blocks in cluster were reserved */ - if (to_reserved == 1) { + if (reserved && to_reserved == 1) { dn->ofs_in_node += cluster_size; goto next; } From 64560e780e907dbd185ebd2de9192c2c80135ee0 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 11 Feb 2025 14:36:57 +0800 Subject: [PATCH 27/48] BACKPORT: FROMGIT: f2fs: fix to avoid panic once fallocation fails for pinfile syzbot reports a f2fs bug as below: ------------[ cut here ]------------ kernel BUG at fs/f2fs/segment.c:2746! CPU: 0 UID: 0 PID: 5323 Comm: syz.0.0 Not tainted 6.13.0-rc2-syzkaller-00018-g7cb1b4663150 #0 RIP: 0010:get_new_segment fs/f2fs/segment.c:2746 [inline] RIP: 0010:new_curseg+0x1f52/0x1f70 fs/f2fs/segment.c:2876 Call Trace: __allocate_new_segment+0x1ce/0x940 fs/f2fs/segment.c:3210 f2fs_allocate_new_section fs/f2fs/segment.c:3224 [inline] f2fs_allocate_pinning_section+0xfa/0x4e0 fs/f2fs/segment.c:3238 f2fs_expand_inode_data+0x696/0xca0 fs/f2fs/file.c:1830 f2fs_fallocate+0x537/0xa10 fs/f2fs/file.c:1940 vfs_fallocate+0x569/0x6e0 fs/open.c:327 do_vfs_ioctl+0x258c/0x2e40 fs/ioctl.c:885 __do_sys_ioctl fs/ioctl.c:904 [inline] __se_sys_ioctl+0x80/0x170 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Concurrent pinfile allocation may run out of free section, result in panic in get_new_segment(), let's expand pin_sem lock coverage to include f2fs_gc(), so that we can make sure to reclaim enough free space for following allocation. In addition, do below changes to enhance error path handling: - call f2fs_bug_on() only in non-pinfile allocation path in get_new_segment(). - call reset_curseg_fields() to reset all fields of curseg in new_curseg() Fixes: f5a53edcf01e ("f2fs: support aligned pinned file") Reported-by: syzbot+15669ec8c35ddf6c3d43@syzkaller.appspotmail.com Closes: https://lore.kernel.org/linux-f2fs-devel/675cd64e.050a0220.37aaf.00bb.GAE@google.com Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Bug: 399583169 (cherry picked from commit 48ea8b200414ac69ea96f4c231f5c7ef1fbeffef https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) Link: https://lore.kernel.org/linux-f2fs-devel/20250211063657.405289-1-chao@kernel.org/ [Jaegeuk: apply the pin_sem control only.] Change-Id: Ie98beaed369e87f1fd14d10fb0e94b706f0bdd23 --- fs/f2fs/file.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index e8ba98a18598..f6b133f373db 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1808,16 +1808,18 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, map.m_len = sec_blks; next_alloc: + f2fs_down_write(&sbi->pin_sem); + if (has_not_enough_free_secs(sbi, 0, GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) { f2fs_down_write(&sbi->gc_lock); err = f2fs_gc(sbi, &gc_control); - if (err && err != -ENODATA) + if (err && err != -ENODATA) { + f2fs_up_write(&sbi->pin_sem); goto out_err; + } } - f2fs_down_write(&sbi->pin_sem); - f2fs_lock_op(sbi); f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); f2fs_unlock_op(sbi); From 4da91a8e563c434008b81c8e047ad2de5ae0bc6b Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 12 Mar 2025 17:01:25 +0800 Subject: [PATCH 28/48] BACKPORT: FROMGIT: f2fs: fix to avoid running out of free segments If checkpoint is disabled, GC can not reclaim any segments, we need to detect such condition and bail out from fallocate() of a pinfile, rather than letting allocator running out of free segment, which may cause f2fs to be shutdown. reproducer: mkfs.f2fs -f /dev/vda 16777216 mount -o checkpoint=disable:10% /dev/vda /mnt/f2fs for ((i=0;i<4096;i++)) do { dd if=/dev/zero of=/mnt/f2fs/$i bs=1M count=1; } done sync for ((i=0;i<4096;i+=2)) do { rm /mnt/f2fs/$i; } done sync touch /mnt/f2fs/pinfile f2fs_io pinfile set /mnt/f2fs/pinfile f2fs_io fallocate 0 0 4201644032 /mnt/f2fs/pinfile cat /sys/kernel/debug/f2fs/status output: - Free: 0 (0) Fixes: f5a53edcf01e ("f2fs: support aligned pinned file") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Bug: 399583169 (cherry picked from commit f7f8932ca6bb22494ef6db671633ad3b4d982271 https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) Link: https://lore.kernel.org/linux-f2fs-devel/20250312090125.4014447-1-chao@kernel.org/ [Jaegeuk Kim: replace f2fs_warn_ratelimited with f2fs_warn] Change-Id: If19aa65412e6ed59f1c15a4a29e210679ec260a0 --- fs/f2fs/file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f6b133f373db..a715231ab5a8 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1810,6 +1810,18 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, next_alloc: f2fs_down_write(&sbi->pin_sem); + if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { + if (has_not_enough_free_secs(sbi, 0, 0)) { + f2fs_up_write(&sbi->pin_sem); + err = -ENOSPC; + f2fs_warn(sbi, + "ino:%lu, start:%lu, end:%lu, need to trigger GC to " + "reclaim enough free segment when checkpoint is enabled", + inode->i_ino, pg_start, pg_end); + goto out_err; + } + } + if (has_not_enough_free_secs(sbi, 0, GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) { f2fs_down_write(&sbi->gc_lock); From 0ad7fae66c7f1532c7ce25938b322d7536ef89b8 Mon Sep 17 00:00:00 2001 From: Dongbum Kim Date: Thu, 20 Feb 2025 16:27:03 +0900 Subject: [PATCH 29/48] ANDROID: printk: add vendor hook to logging during hibernation If hibernation fail, user cannot check log during hibernation. During hibernation, we cannot get any log from copying hibernation image to shutdown the system, for example, write image to storage. A vendor hook copies every log with all loglevel to reserved memory address. We cannot get all loglevels with pstore, so we add vendor hook for copying every log. When the system is rebooted, user can check log from reserved memory address where vendor hook stored in. Bug: 342523877 Change-Id: I31f61378f555ea65ccecfa5b7a96a3ed3e4061a6 Signed-off-by: Dongbum Kim --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/printk.h | 4 ++++ kernel/printk/printk.c | 1 + 3 files changed, 6 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index bddbde83c145..d76fdab3b839 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -473,3 +473,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sdhci_get_cd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_trigger_vendor_lmk_kill); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_map_pages_range); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vprintk_store); diff --git a/include/trace/hooks/printk.h b/include/trace/hooks/printk.h index 2598490b1449..15bd58546bc1 100644 --- a/include/trace/hooks/printk.h +++ b/include/trace/hooks/printk.h @@ -13,6 +13,10 @@ DECLARE_HOOK(android_vh_printk_hotplug, TP_PROTO(int *flag), TP_ARGS(flag)); +DECLARE_HOOK(android_vh_vprintk_store, + TP_PROTO(u64 time, char *m, size_t len), + TP_ARGS(time, m, len)); + #endif /* _TRACE_HOOK_PRINTK_H */ /* This part must be outside protection */ #include diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 0a99fd63232d..f6d1c6a4f868 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2248,6 +2248,7 @@ int vprintk_store(int facility, int level, r.info->flags = flags & 0x1f; r.info->ts_nsec = ts_nsec; r.info->caller_id = caller_id; + trace_android_vh_vprintk_store(r.info->ts_nsec, r.text_buf, r.info->text_len); if (dev_info) memcpy(&r.info->dev_info, dev_info, sizeof(r.info->dev_info)); From 33c9d4844afc450ad2ceea015556968b9b162961 Mon Sep 17 00:00:00 2001 From: Dongbum Kim Date: Fri, 7 Mar 2025 20:13:33 +0900 Subject: [PATCH 30/48] ANDROID: Update the ABI symbol list Adding the following symbols: - __traceiter_android_vh_vprintk_store - __tracepoint_android_vh_vprintk_store Bug: 342523877 Change-Id: I8ddbe5f40960a9f04084da5b0fbdc06eadab0746 Signed-off-by: Dongbum Kim --- android/abi_gki_aarch64.stg | 28 ++++++++++++++++++++++++++++ android/abi_gki_aarch64_qcom | 2 ++ 2 files changed, 30 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 3ddfc4d80af9..8d2c8624042b 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -324349,6 +324349,14 @@ function { parameter_id: 0x0ed82db2 parameter_id: 0x082be49e } +function { + id: 0x99e5c681 + return_type_id: 0x6720d32f + parameter_id: 0x18bd6530 + parameter_id: 0x92233392 + parameter_id: 0x0483e6f8 + parameter_id: 0xf435685e +} function { id: 0x99e6ede5 return_type_id: 0x6720d32f @@ -350177,6 +350185,15 @@ elf_symbol { type_id: 0x9a235f02 full_name: "__traceiter_android_vh_vmscan_kswapd_done" } +elf_symbol { + id: 0xac83aa3b + name: "__traceiter_android_vh_vprintk_store" + is_defined: true + symbol_type: FUNCTION + crc: 0x0e5e212c + type_id: 0x99e5c681 + full_name: "__traceiter_android_vh_vprintk_store" +} elf_symbol { id: 0xb0bf7fd6 name: "__traceiter_android_vh_watchdog_timer_softlockup" @@ -355208,6 +355225,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_vh_vmscan_kswapd_done" } +elf_symbol { + id: 0x743f545d + name: "__tracepoint_android_vh_vprintk_store" + is_defined: true + symbol_type: OBJECT + crc: 0x36987c5d + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_vh_vprintk_store" +} elf_symbol { id: 0x42dbeb24 name: "__tracepoint_android_vh_watchdog_timer_softlockup" @@ -418715,6 +418741,7 @@ interface { symbol_id: 0xd0e4682b symbol_id: 0x08824ed3 symbol_id: 0xcbec9d66 + symbol_id: 0xac83aa3b symbol_id: 0xb0bf7fd6 symbol_id: 0xae5e5469 symbol_id: 0x6911084f @@ -419274,6 +419301,7 @@ interface { symbol_id: 0x990b2371 symbol_id: 0xe100c3ad symbol_id: 0x55476a7c + symbol_id: 0x743f545d symbol_id: 0x42dbeb24 symbol_id: 0xa13f65ff symbol_id: 0xf57e8f65 diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index ccd74d22f185..6e0defcfa479 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -3539,6 +3539,7 @@ __traceiter_android_vh_ufs_send_uic_command __traceiter_android_vh_ufs_update_sdev __traceiter_android_vh_update_topology_flags_workfn + __traceiter_android_vh_vprintk_store __traceiter_binder_transaction_received __traceiter_cpu_frequency_limits __traceiter_cpu_idle @@ -3692,6 +3693,7 @@ __tracepoint_android_vh_ufs_send_uic_command __tracepoint_android_vh_ufs_update_sdev __tracepoint_android_vh_update_topology_flags_workfn + __tracepoint_android_vh_vprintk_store __tracepoint_binder_transaction_received __tracepoint_cpu_frequency_limits __tracepoint_cpu_idle From f3c4686f770c57a09e2e060158bd2eff4705edfe Mon Sep 17 00:00:00 2001 From: Srinivasarao Pathipati Date: Mon, 17 Feb 2025 19:50:35 +0530 Subject: [PATCH 31/48] ANDROID: abi_gki_aarch64_qcom: Add xas_load Add xas_load to qcom abi symbol list. Bug: 397560786 Change-Id: Ia4a7bab9c2f7670fd62b7aba6a8858a1c1890969 Signed-off-by: Ravi Kumar Bokka Signed-off-by: Srinivasarao Pathipati --- android/abi_gki_aarch64.stg | 15 +++++++++++++++ android/abi_gki_aarch64_qcom | 1 + 2 files changed, 16 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 8d2c8624042b..5fec7a803f38 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -310492,6 +310492,11 @@ function { parameter_id: 0x10673339 parameter_id: 0x18a2fb63 } +function { + id: 0x5e72d005 + return_type_id: 0x18bd6530 + parameter_id: 0x239187d3 +} function { id: 0x5e864c76 return_type_id: 0x2560a232 @@ -416938,6 +416943,15 @@ elf_symbol { type_id: 0x5ebf0597 full_name: "xas_find" } +elf_symbol { + id: 0x38562df0 + name: "xas_load" + is_defined: true + symbol_type: FUNCTION + crc: 0x31d34278 + type_id: 0x5e72d005 + full_name: "xas_load" +} elf_symbol { id: 0x0fe35b07 name: "xas_pause" @@ -426157,6 +426171,7 @@ interface { symbol_id: 0xaa425530 symbol_id: 0x9b05d33a symbol_id: 0xb5ba02d4 + symbol_id: 0x38562df0 symbol_id: 0x0fe35b07 symbol_id: 0xebb799b4 symbol_id: 0xcaf4c4fe diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index 6e0defcfa479..b037e1bc50e9 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -4165,6 +4165,7 @@ __xa_insert xa_load xa_store + xas_load xdp_convert_zc_to_xdp_frame xdp_do_flush xdp_do_redirect From cfa792a7764ddae9f34910cbd4e6390a928a4e42 Mon Sep 17 00:00:00 2001 From: Yeongjin Gil Date: Fri, 14 Mar 2025 21:06:51 +0900 Subject: [PATCH 32/48] FROMGIT: f2fs: fix to avoid atomicity corruption of atomic file In the case of the following call stack for an atomic file, FI_DIRTY_INODE is set, but FI_ATOMIC_DIRTIED is not subsequently set. f2fs_file_write_iter f2fs_map_blocks f2fs_reserve_new_blocks inc_valid_block_count __mark_inode_dirty(dquot) f2fs_dirty_inode If FI_ATOMIC_DIRTIED is not set, atomic file can encounter corruption due to a mismatch between old file size and new data. To resolve this issue, I changed to set FI_ATOMIC_DIRTIED when FI_DIRTY_INODE is set. This ensures that FI_DIRTY_INODE, which was previously cleared by the Writeback thread during the commit atomic, is set and i_size is updated. Cc: Fixes: fccaa81de87e ("f2fs: prevent atomic file from being dirtied before commit") Reviewed-by: Sungjong Seo Reviewed-by: Sunmin Jeong Signed-off-by: Yeongjin Gil Reviewed-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Bug: 381519582 (cherry picked from commit f098aeba04c9328571567dca45159358a250240c https: //git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) Link: https://lore.kernel.org/linux-f2fs-devel/20250314120651.443184-1-youngjin.gil@samsung.com/ Change-Id: I7ce87dfbc2525ae185ae6c22671e98ecf021b988 --- fs/f2fs/inode.c | 4 +--- fs/f2fs/super.c | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 706464364966..d3e10049567f 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -33,10 +33,8 @@ void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) if (f2fs_inode_dirtied(inode, sync)) return; - if (f2fs_is_atomic_file(inode)) { - set_inode_flag(inode, FI_ATOMIC_DIRTIED); + if (f2fs_is_atomic_file(inode)) return; - } mark_inode_dirty_sync(inode); } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 830209f65e76..d614a82e2703 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1533,6 +1533,10 @@ int f2fs_inode_dirtied(struct inode *inode, bool sync) inc_page_count(sbi, F2FS_DIRTY_IMETA); } spin_unlock(&sbi->inode_lock[DIRTY_META]); + + if (!ret && f2fs_is_atomic_file(inode)) + set_inode_flag(inode, FI_ATOMIC_DIRTIED); + return ret; } From e2647b0fb4204838e32275f85859b029dc9f36b4 Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Mon, 18 Nov 2024 22:03:43 +0100 Subject: [PATCH 33/48] UPSTREAM: bpf, vsock: Invoke proto::close on close() commit 135ffc7becc82cfb84936ae133da7969220b43b2 upstream. vsock defines a BPF callback to be invoked when close() is called. However, this callback is never actually executed. As a result, a closed vsock socket is not automatically removed from the sockmap/sockhash. Introduce a dummy vsock_close() and make vsock_release() call proto::close. Note: changes in __vsock_release() look messy, but it's only due to indent level reduction and variables xmas tree reorder. Bug: 396331793 Fixes: 634f1a7110b4 ("vsock: support sockmap") Signed-off-by: Michal Luczaj Reviewed-by: Stefano Garzarella Reviewed-by: Luigi Leonardi Link: https://lore.kernel.org/r/20241118-vsock-bpf-poll-close-v1-3-f1b9669cacdc@rbox.co Signed-off-by: Alexei Starovoitov Acked-by: John Fastabend [LL: There is no sockmap support for this kernel version. This patch has been backported because it helps reduce conflicts on future backports] Signed-off-by: Luigi Leonardi Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 13a4362ab83cd4c3a996836c2be81a7e90f04302) Signed-off-by: Lee Jones Change-Id: I8aefa411aa1ef317743deb600aaa4a9cdd52abd3 --- net/vmw_vsock/af_vsock.c | 67 ++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index a62d89be1584..9dab6adf5d4f 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -118,12 +118,14 @@ static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr); static void vsock_sk_destruct(struct sock *sk); static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); +static void vsock_close(struct sock *sk, long timeout); /* Protocol family. */ static struct proto vsock_proto = { .name = "AF_VSOCK", .owner = THIS_MODULE, .obj_size = sizeof(struct vsock_sock), + .close = vsock_close, }; /* The default peer timeout indicates how long we will wait for a peer response @@ -805,39 +807,37 @@ static bool sock_type_connectible(u16 type) static void __vsock_release(struct sock *sk, int level) { - if (sk) { - struct sock *pending; - struct vsock_sock *vsk; + struct vsock_sock *vsk; + struct sock *pending; - vsk = vsock_sk(sk); - pending = NULL; /* Compiler warning. */ + vsk = vsock_sk(sk); + pending = NULL; /* Compiler warning. */ - /* When "level" is SINGLE_DEPTH_NESTING, use the nested - * version to avoid the warning "possible recursive locking - * detected". When "level" is 0, lock_sock_nested(sk, level) - * is the same as lock_sock(sk). - */ - lock_sock_nested(sk, level); + /* When "level" is SINGLE_DEPTH_NESTING, use the nested + * version to avoid the warning "possible recursive locking + * detected". When "level" is 0, lock_sock_nested(sk, level) + * is the same as lock_sock(sk). + */ + lock_sock_nested(sk, level); - if (vsk->transport) - vsk->transport->release(vsk); - else if (sock_type_connectible(sk->sk_type)) - vsock_remove_sock(vsk); + if (vsk->transport) + vsk->transport->release(vsk); + else if (sock_type_connectible(sk->sk_type)) + vsock_remove_sock(vsk); - sock_orphan(sk); - sk->sk_shutdown = SHUTDOWN_MASK; + sock_orphan(sk); + sk->sk_shutdown = SHUTDOWN_MASK; - skb_queue_purge(&sk->sk_receive_queue); + skb_queue_purge(&sk->sk_receive_queue); - /* Clean up any sockets that never were accepted. */ - while ((pending = vsock_dequeue_accept(sk)) != NULL) { - __vsock_release(pending, SINGLE_DEPTH_NESTING); - sock_put(pending); - } - - release_sock(sk); - sock_put(sk); + /* Clean up any sockets that never were accepted. */ + while ((pending = vsock_dequeue_accept(sk)) != NULL) { + __vsock_release(pending, SINGLE_DEPTH_NESTING); + sock_put(pending); } + + release_sock(sk); + sock_put(sk); } static void vsock_sk_destruct(struct sock *sk) @@ -914,9 +914,22 @@ void vsock_data_ready(struct sock *sk) } EXPORT_SYMBOL_GPL(vsock_data_ready); +/* Dummy callback required by sockmap. + * See unconditional call of saved_close() in sock_map_close(). + */ +static void vsock_close(struct sock *sk, long timeout) +{ +} + static int vsock_release(struct socket *sock) { - __vsock_release(sock->sk, 0); + struct sock *sk = sock->sk; + + if (!sk) + return 0; + + sk->sk_prot->close(sk, 0); + __vsock_release(sk, 0); sock->sk = NULL; sock->state = SS_FREE; From 7f11cc02d9eeec5c0eca76ddfa5f5f1c3c6688f2 Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Tue, 28 Jan 2025 14:15:27 +0100 Subject: [PATCH 34/48] UPSTREAM: vsock: Keep the binding until socket destruction commit fcdd2242c0231032fc84e1404315c245ae56322a upstream. Preserve sockets bindings; this includes both resulting from an explicit bind() and those implicitly bound through autobind during connect(). Prevents socket unbinding during a transport reassignment, which fixes a use-after-free: 1. vsock_create() (refcnt=1) calls vsock_insert_unbound() (refcnt=2) 2. transport->release() calls vsock_remove_bound() without checking if sk was bound and moved to bound list (refcnt=1) 3. vsock_bind() assumes sk is in unbound list and before __vsock_insert_bound(vsock_bound_sockets()) calls __vsock_remove_bound() which does: list_del_init(&vsk->bound_table); // nop sock_put(&vsk->sk); // refcnt=0 BUG: KASAN: slab-use-after-free in __vsock_bind+0x62e/0x730 Read of size 4 at addr ffff88816b46a74c by task a.out/2057 dump_stack_lvl+0x68/0x90 print_report+0x174/0x4f6 kasan_report+0xb9/0x190 __vsock_bind+0x62e/0x730 vsock_bind+0x97/0xe0 __sys_bind+0x154/0x1f0 __x64_sys_bind+0x6e/0xb0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Allocated by task 2057: kasan_save_stack+0x1e/0x40 kasan_save_track+0x10/0x30 __kasan_slab_alloc+0x85/0x90 kmem_cache_alloc_noprof+0x131/0x450 sk_prot_alloc+0x5b/0x220 sk_alloc+0x2c/0x870 __vsock_create.constprop.0+0x2e/0xb60 vsock_create+0xe4/0x420 __sock_create+0x241/0x650 __sys_socket+0xf2/0x1a0 __x64_sys_socket+0x6e/0xb0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Freed by task 2057: kasan_save_stack+0x1e/0x40 kasan_save_track+0x10/0x30 kasan_save_free_info+0x37/0x60 __kasan_slab_free+0x4b/0x70 kmem_cache_free+0x1a1/0x590 __sk_destruct+0x388/0x5a0 __vsock_bind+0x5e1/0x730 vsock_bind+0x97/0xe0 __sys_bind+0x154/0x1f0 __x64_sys_bind+0x6e/0xb0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e refcount_t: addition on 0; use-after-free. WARNING: CPU: 7 PID: 2057 at lib/refcount.c:25 refcount_warn_saturate+0xce/0x150 RIP: 0010:refcount_warn_saturate+0xce/0x150 __vsock_bind+0x66d/0x730 vsock_bind+0x97/0xe0 __sys_bind+0x154/0x1f0 __x64_sys_bind+0x6e/0xb0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e refcount_t: underflow; use-after-free. WARNING: CPU: 7 PID: 2057 at lib/refcount.c:28 refcount_warn_saturate+0xee/0x150 RIP: 0010:refcount_warn_saturate+0xee/0x150 vsock_remove_bound+0x187/0x1e0 __vsock_release+0x383/0x4a0 vsock_release+0x90/0x120 __sock_release+0xa3/0x250 sock_close+0x14/0x20 __fput+0x359/0xa80 task_work_run+0x107/0x1d0 do_exit+0x847/0x2560 do_group_exit+0xb8/0x250 __x64_sys_exit_group+0x3a/0x50 x64_sys_call+0xfec/0x14f0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Bug: 396331793 Fixes: c0cfa2d8a788 ("vsock: add multi-transports support") Reviewed-by: Stefano Garzarella Signed-off-by: Michal Luczaj Link: https://patch.msgid.link/20250128-vsock-transport-vs-autobind-v3-1-1cf57065b770@rbox.co Signed-off-by: Jakub Kicinski Signed-off-by: Luigi Leonardi Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 42b33381e5e1f2b967dc4fb4221ddb9aaf10d197) Signed-off-by: Lee Jones Change-Id: Ia6e19299e44641fcd178000349e0da94012f659e --- net/vmw_vsock/af_vsock.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 9dab6adf5d4f..5cb91def283d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -335,7 +335,10 @@ EXPORT_SYMBOL_GPL(vsock_find_connected_socket); void vsock_remove_sock(struct vsock_sock *vsk) { - vsock_remove_bound(vsk); + /* Transport reassignment must not remove the binding. */ + if (sock_flag(sk_vsock(vsk), SOCK_DEAD)) + vsock_remove_bound(vsk); + vsock_remove_connected(vsk); } EXPORT_SYMBOL_GPL(vsock_remove_sock); @@ -820,12 +823,13 @@ static void __vsock_release(struct sock *sk, int level) */ lock_sock_nested(sk, level); + sock_orphan(sk); + if (vsk->transport) vsk->transport->release(vsk); else if (sock_type_connectible(sk->sk_type)) vsock_remove_sock(vsk); - sock_orphan(sk); sk->sk_shutdown = SHUTDOWN_MASK; skb_queue_purge(&sk->sk_receive_queue); From cd0ebcd1757913ed6232b90203f586cd4b59de42 Mon Sep 17 00:00:00 2001 From: Michal Luczaj Date: Mon, 10 Feb 2025 13:15:00 +0100 Subject: [PATCH 35/48] UPSTREAM: vsock: Orphan socket after transport release commit 78dafe1cf3afa02ed71084b350713b07e72a18fb upstream. During socket release, sock_orphan() is called without considering that it sets sk->sk_wq to NULL. Later, if SO_LINGER is enabled, this leads to a null pointer dereferenced in virtio_transport_wait_close(). Orphan the socket only after transport release. Partially reverts the 'Fixes:' commit. KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f] lock_acquire+0x19e/0x500 _raw_spin_lock_irqsave+0x47/0x70 add_wait_queue+0x46/0x230 virtio_transport_release+0x4e7/0x7f0 __vsock_release+0xfd/0x490 vsock_release+0x90/0x120 __sock_release+0xa3/0x250 sock_close+0x14/0x20 __fput+0x35e/0xa90 __x64_sys_close+0x78/0xd0 do_syscall_64+0x93/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e Bug: 396331793 Reported-by: syzbot+9d55b199192a4be7d02c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9d55b199192a4be7d02c Fixes: fcdd2242c023 ("vsock: Keep the binding until socket destruction") Tested-by: Luigi Leonardi Reviewed-by: Luigi Leonardi Signed-off-by: Michal Luczaj Link: https://patch.msgid.link/20250210-vsock-linger-nullderef-v3-1-ef6244d02b54@rbox.co Signed-off-by: Jakub Kicinski Signed-off-by: Luigi Leonardi Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 631e00fdac7acca676103d6cbc96eb152625f449) Signed-off-by: Lee Jones Change-Id: I61ef914e5f706ee1c9dd2b9f95cbc69020fe8f00 --- net/vmw_vsock/af_vsock.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5cb91def283d..75d3b8ef5a42 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -823,13 +823,19 @@ static void __vsock_release(struct sock *sk, int level) */ lock_sock_nested(sk, level); - sock_orphan(sk); + /* Indicate to vsock_remove_sock() that the socket is being released and + * can be removed from the bound_table. Unlike transport reassignment + * case, where the socket must remain bound despite vsock_remove_sock() + * being called from the transport release() callback. + */ + sock_set_flag(sk, SOCK_DEAD); if (vsk->transport) vsk->transport->release(vsk); else if (sock_type_connectible(sk->sk_type)) vsock_remove_sock(vsk); + sock_orphan(sk); sk->sk_shutdown = SHUTDOWN_MASK; skb_queue_purge(&sk->sk_receive_queue); From 92ada4b4c2155797c4cece9d7303392a436f1bab Mon Sep 17 00:00:00 2001 From: Quang Le Date: Mon, 3 Feb 2025 16:58:38 -0800 Subject: [PATCH 36/48] UPSTREAM: pfifo_tail_enqueue: Drop new packet when sch->limit == 0 commit 647cef20e649c576dff271e018d5d15d998b629d upstream. Expected behaviour: In case we reach scheduler's limit, pfifo_tail_enqueue() will drop a packet in scheduler's queue and decrease scheduler's qlen by one. Then, pfifo_tail_enqueue() enqueue new packet and increase scheduler's qlen by one. Finally, pfifo_tail_enqueue() return `NET_XMIT_CN` status code. Weird behaviour: In case we set `sch->limit == 0` and trigger pfifo_tail_enqueue() on a scheduler that has no packet, the 'drop a packet' step will do nothing. This means the scheduler's qlen still has value equal 0. Then, we continue to enqueue new packet and increase scheduler's qlen by one. In summary, we can leverage pfifo_tail_enqueue() to increase qlen by one and return `NET_XMIT_CN` status code. The problem is: Let's say we have two qdiscs: Qdisc_A and Qdisc_B. - Qdisc_A's type must have '->graft()' function to create parent/child relationship. Let's say Qdisc_A's type is `hfsc`. Enqueue packet to this qdisc will trigger `hfsc_enqueue`. - Qdisc_B's type is pfifo_head_drop. Enqueue packet to this qdisc will trigger `pfifo_tail_enqueue`. - Qdisc_B is configured to have `sch->limit == 0`. - Qdisc_A is configured to route the enqueued's packet to Qdisc_B. Enqueue packet through Qdisc_A will lead to: - hfsc_enqueue(Qdisc_A) -> pfifo_tail_enqueue(Qdisc_B) - Qdisc_B->q.qlen += 1 - pfifo_tail_enqueue() return `NET_XMIT_CN` - hfsc_enqueue() check for `NET_XMIT_SUCCESS` and see `NET_XMIT_CN` => hfsc_enqueue() don't increase qlen of Qdisc_A. The whole process lead to a situation where Qdisc_A->q.qlen == 0 and Qdisc_B->q.qlen == 1. Replace 'hfsc' with other type (for example: 'drr') still lead to the same problem. This violate the design where parent's qlen should equal to the sum of its childrens'qlen. Bug impact: This issue can be used for user->kernel privilege escalation when it is reachable. Bug: 395539871 Fixes: 57dbb2d83d10 ("sched: add head drop fifo queue") Reported-by: Quang Le Signed-off-by: Quang Le Signed-off-by: Cong Wang Link: https://patch.msgid.link/20250204005841.223511-2-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 79a955ea4a2e5ddf4a36328959de0de496419888) Signed-off-by: Lee Jones Change-Id: I94a3851190671bc98666cb659e8419ab2767fb03 --- net/sched/sch_fifo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index e1040421b797..1080d89f9178 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -39,6 +39,9 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch, { unsigned int prev_backlog; + if (unlikely(sch->limit == 0)) + return qdisc_drop(skb, sch, to_free); + if (likely(sch->q.qlen < sch->limit)) return qdisc_enqueue_tail(skb, sch); From 2afd0800a730081c941189e3174ed0a30f4c59e7 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Thu, 16 Jan 2025 10:21:57 +0100 Subject: [PATCH 37/48] UPSTREAM: net: avoid race between device unregistration and ethnl ops [ Upstream commit 12e070eb6964b341b41677fd260af5a305316a1f ] The following trace can be seen if a device is being unregistered while its number of channels are being modified. DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: CPU: 3 PID: 3754 at kernel/locking/mutex.c:564 __mutex_lock+0xc8a/0x1120 CPU: 3 UID: 0 PID: 3754 Comm: ethtool Not tainted 6.13.0-rc6+ #771 RIP: 0010:__mutex_lock+0xc8a/0x1120 Call Trace: ethtool_check_max_channel+0x1ea/0x880 ethnl_set_channels+0x3c3/0xb10 ethnl_default_set_doit+0x306/0x650 genl_family_rcv_msg_doit+0x1e3/0x2c0 genl_rcv_msg+0x432/0x6f0 netlink_rcv_skb+0x13d/0x3b0 genl_rcv+0x28/0x40 netlink_unicast+0x42e/0x720 netlink_sendmsg+0x765/0xc20 __sys_sendto+0x3ac/0x420 __x64_sys_sendto+0xe0/0x1c0 do_syscall_64+0x95/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e This is because unregister_netdevice_many_notify might run before the rtnl lock section of ethnl operations, eg. set_channels in the above example. In this example the rss lock would be destroyed by the device unregistration path before being used again, but in general running ethnl operations while dismantle has started is not a good idea. Fix this by denying any operation on devices being unregistered. A check was already there in ethnl_ops_begin, but not wide enough. Note that the same issue cannot be seen on the ioctl version (__dev_ethtool) because the device reference is retrieved from within the rtnl lock section there. Once dismantle started, the net device is unlisted and no reference will be found. Bug: 392852041 Fixes: dde91ccfa25f ("ethtool: do not perform operations on net devices being unregistered") Signed-off-by: Antoine Tenart Reviewed-by: Przemek Kitszel Reviewed-by: Edward Cree Link: https://patch.msgid.link/20250116092159.50890-1-atenart@kernel.org Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin (cherry picked from commit b1cb37a31a482df3dd35a6ac166282dac47664f4) Signed-off-by: Lee Jones Change-Id: I56dbd897bb6db194d1eab1d5370796d2e3142fe2 --- net/ethtool/netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c index fc4ccecf9495..e5efdf2817ef 100644 --- a/net/ethtool/netlink.c +++ b/net/ethtool/netlink.c @@ -41,7 +41,7 @@ int ethnl_ops_begin(struct net_device *dev) pm_runtime_get_sync(dev->dev.parent); if (!netif_device_present(dev) || - dev->reg_state == NETREG_UNREGISTERING) { + dev->reg_state >= NETREG_UNREGISTERING) { ret = -ENODEV; goto err; } From 6bd3e435f2e8eeada09275a24f3013801756edfb Mon Sep 17 00:00:00 2001 From: Jianan Huang Date: Fri, 24 Jan 2025 13:57:51 +0800 Subject: [PATCH 38/48] UPSTREAM: f2fs: fix inconsistent dirty state of atomic file When testing the atomic write fix patches, the f2fs_bug_on was triggered as below: ------------[ cut here ]------------ kernel BUG at fs/f2fs/inode.c:935! Oops: invalid opcode: 0000 [#1] PREEMPT SMP PTI CPU: 3 UID: 0 PID: 257 Comm: bash Not tainted 6.13.0-rc1-00033-gc283a70d3497 #5 RIP: 0010:f2fs_evict_inode+0x50f/0x520 Call Trace: ? __die_body+0x65/0xb0 ? die+0x9f/0xc0 ? do_trap+0xa1/0x170 ? f2fs_evict_inode+0x50f/0x520 ? f2fs_evict_inode+0x50f/0x520 ? handle_invalid_op+0x65/0x80 ? f2fs_evict_inode+0x50f/0x520 ? exc_invalid_op+0x39/0x50 ? asm_exc_invalid_op+0x1a/0x20 ? __pfx_f2fs_get_dquots+0x10/0x10 ? f2fs_evict_inode+0x50f/0x520 ? f2fs_evict_inode+0x2e5/0x520 evict+0x186/0x2f0 prune_icache_sb+0x75/0xb0 super_cache_scan+0x1a8/0x200 do_shrink_slab+0x163/0x320 shrink_slab+0x2fc/0x470 drop_slab+0x82/0xf0 drop_caches_sysctl_handler+0x4e/0xb0 proc_sys_call_handler+0x183/0x280 vfs_write+0x36d/0x450 ksys_write+0x68/0xd0 do_syscall_64+0xc8/0x1a0 ? arch_exit_to_user_mode_prepare+0x11/0x60 ? irqentry_exit_to_user_mode+0x7e/0xa0 The root cause is: f2fs uses FI_ATOMIC_DIRTIED to indicate dirty atomic files during commit. If the inode is dirtied during commit, such as by f2fs_i_pino_write, the vfs inode keeps clean and the f2fs inode is set to FI_DIRTY_INODE. The FI_DIRTY_INODE flag cann't be cleared by write_inode later due to the clean vfs inode. Finally, f2fs_bug_on is triggered due to this inconsistent state when evict. To reproduce this situation: - fd = open("/mnt/test.db", O_WRONLY) - ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE) - mv /mnt/test.db /mnt/test1.db - ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE) - echo 3 > /proc/sys/vm/drop_caches To fix this problem, clear FI_DIRTY_INODE after commit, then f2fs_mark_inode_dirty_sync will ensure a consistent dirty state. Bug: 402645924 Fixes: fccaa81de87e ("f2fs: prevent atomic file from being dirtied before commit") Change-Id: I2c637b4bc544453b07ab124527efb694da9b757f Signed-off-by: Yunlei He Signed-off-by: Jianan Huang Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit 03511e936916873bf880e6678c98d5fb59c19742) (cherry picked from commit 0e0c530475d05e8d91972957761d08ab0f0e931d) (cherry picked from commit 52d776ea9f68f0101bd6c1b42ac98e9b697bfe7b) --- fs/f2fs/segment.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 6b6baf8b64ae..7f07981a7b04 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -201,6 +201,12 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean) clear_inode_flag(inode, FI_ATOMIC_FILE); if (is_inode_flag_set(inode, FI_ATOMIC_DIRTIED)) { clear_inode_flag(inode, FI_ATOMIC_DIRTIED); + /* + * The vfs inode keeps clean during commit, but the f2fs inode + * doesn't. So clear the dirty state after commit and let + * f2fs_mark_inode_dirty_sync ensure a consistent dirty state. + */ + f2fs_inode_synced(inode); f2fs_mark_inode_dirty_sync(inode, true); } stat_dec_atomic_inode(inode); From d3b0aaa092abb1bf18606aeb0306425aa5e7e446 Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Mon, 17 Mar 2025 11:28:22 +0800 Subject: [PATCH 39/48] ANDROID: Add EXPORT_SYMBOL_GPL for folio_mapcount We need to get the number of folio mappings through folio_mapcount. Later, pages with mapcount higher than a certain threshold will be skipped for reverse mapping to reduce the high load caused by reverse mapping during the recycling process. Bug: 404067677 Change-Id: I21dd847a07fb4e7bb616a3bc01b7d1cdf46e9b0b Signed-off-by: Marcus Ma --- mm/util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/util.c b/mm/util.c index 36b78dac0706..98771d2bdc67 100644 --- a/mm/util.c +++ b/mm/util.c @@ -847,6 +847,7 @@ int folio_mapcount(struct folio *folio) ret -= nr; return ret; } +EXPORT_SYMBOL_GPL(folio_mapcount); /** * folio_copy - Copy the contents of one folio to another. From 7da329f7cf910df4b350b275fd6dd2f28b0d554e Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Mon, 17 Mar 2025 14:54:43 +0800 Subject: [PATCH 40/48] ANDROID: Update the ABI symbol list Adding the following symbols: - folio_mapcount Bug: 404067677 Change-Id: Id8382f108729e23475a652855a75d99ee892c41c Signed-off-by: Marcus Ma --- android/abi_gki_aarch64.stg | 10 ++++++++++ android/abi_gki_aarch64_xiaomi | 1 + 2 files changed, 11 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 5fec7a803f38..0e2571ac21f1 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -375014,6 +375014,15 @@ elf_symbol { type_id: 0xf6f86f1f full_name: "folio_clear_dirty_for_io" } +elf_symbol { + id: 0x4ac51913 + name: "folio_mapcount" + is_defined: true + symbol_type: FUNCTION + crc: 0x77eeba8a + type_id: 0x95dcd734 + full_name: "folio_mapcount" +} elf_symbol { id: 0x159a69a3 name: "folio_mapping" @@ -421512,6 +421521,7 @@ interface { symbol_id: 0x3c7c2553 symbol_id: 0x06c58be7 symbol_id: 0xab55569c + symbol_id: 0x4ac51913 symbol_id: 0x159a69a3 symbol_id: 0xcef0ca54 symbol_id: 0x39840ab2 diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index 91ed87277a20..6775dac3796c 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -472,6 +472,7 @@ __tracepoint_android_vh_page_should_be_protected __traceiter_android_vh_page_referenced_check_bypass __tracepoint_android_vh_page_referenced_check_bypass __page_mapcount +folio_mapcount #required by mi_async_reclaim.ko __traceiter_android_vh_handle_trylock_failed_folio From 9d6305174ccd35517f46a51e7a44eb9348d5a036 Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Sat, 8 Mar 2025 03:46:00 +0000 Subject: [PATCH 41/48] BACKPORT: FROMGIT: mm/page_alloc: add trace event for per-zone watermark setup Patch series "Add tracepoints for lowmem reserves, watermarks and totalreserve_pages", v2. This patchset introduces tracepoints to track changes in the lowmem reserves, watermarks and totalreserve_pages. This helps to track the exact timing of such changes and understand their relation to reclaim activities. The tracepoints added are: mm_setup_per_zone_lowmem_reserve mm_setup_per_zone_wmarks mm_calculate_totalreserve_pagesi This patch (of 3): This commit introduces the `mm_setup_per_zone_wmarks` trace event, which provides detailed insights into the kernel's per-zone watermark configuration, offering precise timing and the ability to correlate watermark changes with specific kernel events. While `/proc/zoneinfo` provides some information about zone watermarks, this trace event offers: 1. The ability to link watermark changes to specific kernel events and logic. 2. The ability to capture rapid or short-lived changes in watermarks that may be missed by user-space polling 3. Diagnosing unexpected kswapd activity or excessive direct reclaim triggered by rapidly changing watermarks. Link: https://lkml.kernel.org/r/20250308034606.2036033-1-liumartin@google.com Link: https://lkml.kernel.org/r/20250308034606.2036033-2-liumartin@google.com Signed-off-by: Martin Liu Acked-by: David Rientjes Cc: Steven Rostedt Cc: Martin Liu Cc: "Masami Hiramatsu (Google)" Cc: Mathieu Desnoyers Signed-off-by: Andrew Morton Bug: 396115949 (cherry picked from commit 8c02048d1c6126527f15752a5e0849dc49cefeeb https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-unstable) Change-Id: I7e326e78542abb6fa5f3ccbe5d61a59f42d7cf2f Signed-off-by: Martin Liu --- include/trace/events/kmem.h | 33 +++++++++++++++++++++++++++++++++ mm/page_alloc.c | 1 + 2 files changed, 34 insertions(+) diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 62df5990c3fc..09b58792762d 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h @@ -342,6 +342,39 @@ TRACE_EVENT(mm_alloc_contig_migrate_range_info, __entry->nr_mapped) ); +TRACE_EVENT(mm_setup_per_zone_wmarks, + + TP_PROTO(struct zone *zone), + + TP_ARGS(zone), + + TP_STRUCT__entry( + __field(int, node_id) + __string(name, zone->name) + __field(unsigned long, watermark_min) + __field(unsigned long, watermark_low) + __field(unsigned long, watermark_high) + __field(unsigned long, watermark_promo) + ), + + TP_fast_assign( + __entry->node_id = zone->zone_pgdat->node_id; + __assign_str(name, zone->name); + __entry->watermark_min = zone->_watermark[WMARK_MIN]; + __entry->watermark_low = zone->_watermark[WMARK_LOW]; + __entry->watermark_high = zone->_watermark[WMARK_HIGH]; + __entry->watermark_promo = zone->_watermark[WMARK_PROMO]; + ), + + TP_printk("node_id=%d zone name=%s watermark min=%lu low=%lu high=%lu promo=%lu", + __entry->node_id, + __get_str(name), + __entry->watermark_min, + __entry->watermark_low, + __entry->watermark_high, + __entry->watermark_promo) +); + /* * Required for uniquely and securely identifying mm in rss_stat tracepoint. */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 28004c549031..ca88e02fdbe4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -9070,6 +9070,7 @@ static void __setup_per_zone_wmarks(void) zone->_watermark[WMARK_LOW] = min_wmark_pages(zone) + tmp; zone->_watermark[WMARK_HIGH] = low_wmark_pages(zone) + tmp; zone->_watermark[WMARK_PROMO] = high_wmark_pages(zone) + tmp; + trace_mm_setup_per_zone_wmarks(zone); spin_unlock_irqrestore(&zone->lock, flags); } From 95baed16639c0928fac06f2a10af71798bba3c01 Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Sat, 8 Mar 2025 03:46:01 +0000 Subject: [PATCH 42/48] BACKPORT: FROMGIT: mm/page_alloc: add trace event for per-zone lowmem reserve setup This commit introduces the `mm_setup_per_zone_lowmem_reserve` trace event,which provides detailed insights into the kernel's per-zone lowmem reserve configuration. The trace event provides precise timestamps, allowing developers to 1. Correlate lowmem reserve changes with specific kernel events and able to diagnose unexpected kswapd or direct reclaim behavior triggered by dynamic changes in lowmem reserve. 2. Know memory allocation failures that occur due to insufficient lowmem reserve, by precisely correlating allocation attempts with reserve adjustments. Link: https://lkml.kernel.org/r/20250308034606.2036033-3-liumartin@google.com Signed-off-by: Martin Liu Acked-by: David Rientjes Cc: "Masami Hiramatsu (Google)" Cc: Mathieu Desnoyers Cc: Steven Rostedt Signed-off-by: Andrew Morton Bug: 396115949 (cherry picked from commit a293aba4a584709889f77a0ad0c45746aecf1b9f https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-unstable) Change-Id: I271fc260ec60645230681bf0afbcd10d84453c88 Signed-off-by: Martin Liu --- include/trace/events/kmem.h | 27 +++++++++++++++++++++++++++ mm/page_alloc.c | 2 ++ 2 files changed, 29 insertions(+) diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 09b58792762d..5b1578a4a89e 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h @@ -375,6 +375,33 @@ TRACE_EVENT(mm_setup_per_zone_wmarks, __entry->watermark_promo) ); +TRACE_EVENT(mm_setup_per_zone_lowmem_reserve, + + TP_PROTO(struct zone *zone, struct zone *upper_zone, long lowmem_reserve), + + TP_ARGS(zone, upper_zone, lowmem_reserve), + + TP_STRUCT__entry( + __field(int, node_id) + __string(name, zone->name) + __string(upper_name, upper_zone->name) + __field(long, lowmem_reserve) + ), + + TP_fast_assign( + __entry->node_id = zone->zone_pgdat->node_id; + __assign_str(name, zone->name); + __assign_str(upper_name, zone->name); + __entry->lowmem_reserve = lowmem_reserve; + ), + + TP_printk("node_id=%d zone name=%s upper_zone name=%s lowmem_reserve_pages=%ld", + __entry->node_id, + __get_str(name), + __get_str(upper_name), + __entry->lowmem_reserve) +); + /* * Required for uniquely and securely identifying mm in rss_stat tracepoint. */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ca88e02fdbe4..aecf77d9a672 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -9007,6 +9007,8 @@ static void setup_per_zone_lowmem_reserve(void) zone->lowmem_reserve[j] = 0; else zone->lowmem_reserve[j] = managed_pages / ratio; + trace_mm_setup_per_zone_lowmem_reserve(zone, upper_zone, + zone->lowmem_reserve[j]); } } } From da6a42c111c874bbc194749c97cc6c0e715e1bcd Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Sat, 8 Mar 2025 03:46:02 +0000 Subject: [PATCH 43/48] FROMGIT: mm/page_alloc: add trace event for totalreserve_pages calculation This commit introduces a new trace event, `mm_calculate_totalreserve_pages`, which reports the new reserve value at the exact time when it takes effect. The `totalreserve_pages` value represents the total amount of memory reserved across all zones and nodes in the system. This reserved memory is crucial for ensuring that critical kernel operations have access to sufficient memory, even under memory pressure. By tracing the `totalreserve_pages` value, developers can gain insights that how the total reserved memory changes over time. Link: https://lkml.kernel.org/r/20250308034606.2036033-4-liumartin@google.com Signed-off-by: Martin Liu Acked-by: David Rientjes Cc: "Masami Hiramatsu (Google)" Cc: Mathieu Desnoyers Cc: Steven Rostedt Signed-off-by: Andrew Morton Bug: 396115949 (cherry picked from commit 15766485e4a51bec2dcce304c089a95550720033 https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-unstable) Change-Id: Iced6ea39ad8a36a50bf4393814b6bca2f64ac3b0 Signed-off-by: Martin Liu --- include/trace/events/kmem.h | 18 ++++++++++++++++++ mm/page_alloc.c | 1 + 2 files changed, 19 insertions(+) diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 5b1578a4a89e..ed3af0df3692 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h @@ -402,6 +402,24 @@ TRACE_EVENT(mm_setup_per_zone_lowmem_reserve, __entry->lowmem_reserve) ); +TRACE_EVENT(mm_calculate_totalreserve_pages, + + TP_PROTO(unsigned long totalreserve_pages), + + TP_ARGS(totalreserve_pages), + + TP_STRUCT__entry( + __field(unsigned long, totalreserve_pages) + ), + + TP_fast_assign( + __entry->totalreserve_pages = totalreserve_pages; + ), + + TP_printk("totalreserve_pages=%lu", __entry->totalreserve_pages) +); + + /* * Required for uniquely and securely identifying mm in rss_stat tracepoint. */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index aecf77d9a672..15087a0d7d71 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -8978,6 +8978,7 @@ static void calculate_totalreserve_pages(void) } } totalreserve_pages = reserve_pages; + trace_mm_calculate_totalreserve_pages(totalreserve_pages); } /* From 2f4537ba6c01c383ed9906916df5b6cee5eb0a4c Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Wed, 19 Mar 2025 10:02:16 +0800 Subject: [PATCH 44/48] ANDROID: vendor_hooks: Skip pages with high memory pressure in shrink_active_list The android_vh_folio_referenced_check_bypass hook reverse-maps and skips pages with high memory pressure in shrink_active_list, preferring to recycle them. This helps reduce memory pressure and improve system performance under high load. Bug: 404067669 Change-Id: Ic10edcef9761df774d6cf18544e7c044bf78d3ed Signed-off-by: Marcus Ma --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/vmscan.h | 3 +++ mm/vmscan.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index d76fdab3b839..663121911094 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -474,3 +474,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_trigger_vendor_lmk_kill); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_map_pages_range); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vprintk_store); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_folio_referenced_check_bypass); diff --git a/include/trace/hooks/vmscan.h b/include/trace/hooks/vmscan.h index fba2efaa294a..94303994f6d6 100644 --- a/include/trace/hooks/vmscan.h +++ b/include/trace/hooks/vmscan.h @@ -79,6 +79,9 @@ DECLARE_HOOK(android_vh_do_folio_trylock, DECLARE_HOOK(android_vh_page_referenced_check_bypass, TP_PROTO(struct folio *folio, unsigned long nr_to_scan, int lru, bool *bypass), TP_ARGS(folio, nr_to_scan, lru, bypass)); +DECLARE_HOOK(android_vh_folio_referenced_check_bypass, + TP_PROTO(struct folio *folio, s8 priority, unsigned long nr_to_scan, int lru, bool *bypass), + TP_ARGS(folio, priority, nr_to_scan, lru, bypass)); DECLARE_HOOK(android_vh_should_memcg_bypass, TP_PROTO(struct mem_cgroup *memcg, int priority, bool *bypass), TP_ARGS(memcg, priority, bypass)); diff --git a/mm/vmscan.c b/mm/vmscan.c index 432471847d37..9dbd8b1ae7a6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2709,6 +2709,8 @@ static void shrink_active_list(unsigned long nr_to_scan, } trace_android_vh_page_referenced_check_bypass(folio, nr_to_scan, lru, &bypass); + trace_android_vh_folio_referenced_check_bypass(folio, sc->priority, + nr_to_scan, lru, &bypass); if (bypass) goto skip_folio_referenced; trace_android_vh_folio_trylock_set(folio); From 5145d157731fcdde380e5da461c483b5080a8df5 Mon Sep 17 00:00:00 2001 From: Marcus Ma Date: Thu, 20 Mar 2025 15:35:39 +0800 Subject: [PATCH 45/48] ANDROID: GKI: update symbol list file for xiaomi add 1 function: android_vh_folio_referenced_check_bypass() Bug: 404067669 Change-Id: I91288be3a33ce839b8371e7f8f0e28b0b163920f Signed-off-by: Marcus Ma --- android/abi_gki_aarch64.stg | 30 ++++++++++++++++++++++++++++++ android/abi_gki_aarch64_xiaomi | 2 ++ 2 files changed, 32 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 0e2571ac21f1..a2d62a61e5ce 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -326329,6 +326329,16 @@ function { parameter_id: 0x1b8590a8 parameter_id: 0x107606b0 } +function { + id: 0x9b20c0a6 + return_type_id: 0x6720d32f + parameter_id: 0x18bd6530 + parameter_id: 0x2170d06d + parameter_id: 0x29b77961 + parameter_id: 0x33756485 + parameter_id: 0x6720d32f + parameter_id: 0x11cfee5a +} function { id: 0x9b222516 return_type_id: 0x6720d32f @@ -348246,6 +348256,15 @@ elf_symbol { type_id: 0x9bc62aec full_name: "__traceiter_android_vh_filemap_read" } +elf_symbol { + id: 0x51030b11 + name: "__traceiter_android_vh_folio_referenced_check_bypass" + is_defined: true + symbol_type: FUNCTION + crc: 0xe1043e73 + type_id: 0x9b20c0a6 + full_name: "__traceiter_android_vh_folio_referenced_check_bypass" +} elf_symbol { id: 0x1fca37bf name: "__traceiter_android_vh_folio_trylock_clear" @@ -353286,6 +353305,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_vh_filemap_read" } +elf_symbol { + id: 0x242ad327 + name: "__tracepoint_android_vh_folio_referenced_check_bypass" + is_defined: true + symbol_type: OBJECT + crc: 0x261bebc9 + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_vh_folio_referenced_check_bypass" +} elf_symbol { id: 0xa3ede5d5 name: "__tracepoint_android_vh_folio_trylock_clear" @@ -418548,6 +418576,7 @@ interface { symbol_id: 0xb7d91f76 symbol_id: 0x4eda1196 symbol_id: 0x158bf9d3 + symbol_id: 0x51030b11 symbol_id: 0x1fca37bf symbol_id: 0xe6702595 symbol_id: 0x9e91661b @@ -419108,6 +419137,7 @@ interface { symbol_id: 0xb34d9200 symbol_id: 0x223c9b64 symbol_id: 0xf61927fd + symbol_id: 0x242ad327 symbol_id: 0xa3ede5d5 symbol_id: 0x539bf337 symbol_id: 0x901d0e89 diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index 6775dac3796c..29dfbb4f0036 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -473,6 +473,8 @@ __traceiter_android_vh_page_referenced_check_bypass __tracepoint_android_vh_page_referenced_check_bypass __page_mapcount folio_mapcount +__traceiter_android_vh_folio_referenced_check_bypass +__tracepoint_android_vh_folio_referenced_check_bypass #required by mi_async_reclaim.ko __traceiter_android_vh_handle_trylock_failed_folio From 2fb96ec85c0e99d7947dc7d81191ca7d87174f4a Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Fri, 21 Mar 2025 08:45:17 +0000 Subject: [PATCH 46/48] ANDROID: vendor_hook: add vendor hook on calculate_totalreserve_pages This vendor hook enables or disables updating the LMKD zone watermark level. Bug: 396115949 Test: build Change-Id: I0089a0586821120e47c46e08bcfea11a1602d516 Signed-off-by: Martin Liu --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/mm.h | 3 +++ mm/page_alloc.c | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 663121911094..7ceecabcaa38 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -475,3 +475,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_trigger_vendor_lmk_kill); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_map_pages_range); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vprintk_store); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_folio_referenced_check_bypass); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_calculate_totalreserve_pages); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 74b76878fe9d..013b85d2c9a7 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -302,6 +302,9 @@ DECLARE_HOOK(android_vh_filemap_map_pages_range, TP_PROTO(struct file *file, pgoff_t orig_start_pgoff, pgoff_t last_pgoff, vm_fault_t ret), TP_ARGS(file, orig_start_pgoff, last_pgoff, ret)); +DECLARE_HOOK(android_vh_calculate_totalreserve_pages, + TP_PROTO(bool *skip), + TP_ARGS(skip)); #endif /* _TRACE_HOOK_MM_H */ /* This part must be outside protection */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 15087a0d7d71..d352b85fef7b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -8950,6 +8950,7 @@ static void calculate_totalreserve_pages(void) struct pglist_data *pgdat; unsigned long reserve_pages = 0; enum zone_type i, j; + bool skip = false; for_each_online_pgdat(pgdat) { @@ -8978,6 +8979,9 @@ static void calculate_totalreserve_pages(void) } } totalreserve_pages = reserve_pages; + trace_android_vh_calculate_totalreserve_pages(&skip); + if (skip) + return; trace_mm_calculate_totalreserve_pages(totalreserve_pages); } From f628136006ccecc881cfba83d59f158e34a49858 Mon Sep 17 00:00:00 2001 From: Martin Liu Date: Sun, 23 Mar 2025 06:26:19 +0000 Subject: [PATCH 47/48] ANDROID: ABI: Update pixel symbol list Adding the following symbols: - __traceiter_android_vh_calculate_totalreserve_pages - __tracepoint_android_vh_calculate_totalreserve_pages Bug: 396115949 Change-Id: I0e17cd9359b1bdc1b5de5c63d75681ee3be1366d Signed-off-by: Martin Liu --- android/abi_gki_aarch64.stg | 20 ++++++++++++++++++++ android/abi_gki_aarch64_pixel | 2 ++ 2 files changed, 22 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index a2d62a61e5ce..8b8d8fa00212 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -347662,6 +347662,15 @@ elf_symbol { type_id: 0x9b54acf0 full_name: "__traceiter_android_vh_bus_iommu_probe" } +elf_symbol { + id: 0xabf171fb + name: "__traceiter_android_vh_calculate_totalreserve_pages" + is_defined: true + symbol_type: FUNCTION + crc: 0xb3aa3227 + type_id: 0x9be885da + full_name: "__traceiter_android_vh_calculate_totalreserve_pages" +} elf_symbol { id: 0xa9225bf8 name: "__traceiter_android_vh_cgroup_attach" @@ -352711,6 +352720,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_vh_bus_iommu_probe" } +elf_symbol { + id: 0x1ff4fc25 + name: "__tracepoint_android_vh_calculate_totalreserve_pages" + is_defined: true + symbol_type: OBJECT + crc: 0x81a86905 + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_vh_calculate_totalreserve_pages" +} elf_symbol { id: 0xd3845a12 name: "__tracepoint_android_vh_cgroup_attach" @@ -418510,6 +418528,7 @@ interface { symbol_id: 0x53fba77d symbol_id: 0xe479b209 symbol_id: 0x31a78b8a + symbol_id: 0xabf171fb symbol_id: 0xa9225bf8 symbol_id: 0x33c527ab symbol_id: 0x5012fcd8 @@ -419071,6 +419090,7 @@ interface { symbol_id: 0x506628ab symbol_id: 0x0d3c7607 symbol_id: 0x527423dc + symbol_id: 0x1ff4fc25 symbol_id: 0xd3845a12 symbol_id: 0x6f146fe1 symbol_id: 0x678bb5ba diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index af98388dc351..8c48602bccf2 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -2455,6 +2455,7 @@ __traceiter_android_vh_usb_dev_resume __traceiter_android_vh_use_amu_fie __traceiter_android_vh_vmscan_kswapd_done + __traceiter_android_vh_calculate_totalreserve_pages __traceiter_clock_set_rate __traceiter_cma_alloc_finish __traceiter_cma_alloc_start @@ -2595,6 +2596,7 @@ __tracepoint_android_vh_usb_dev_resume __tracepoint_android_vh_use_amu_fie __tracepoint_android_vh_vmscan_kswapd_done + __tracepoint_android_vh_calculate_totalreserve_pages __tracepoint_clock_set_rate __tracepoint_cma_alloc_finish __tracepoint_cma_alloc_start From b18db21117e28ab165172b815f106006a87eb7d9 Mon Sep 17 00:00:00 2001 From: Bian Jin chen Date: Tue, 25 Mar 2025 08:49:30 +0800 Subject: [PATCH 48/48] ANDROID: GKI: Update rockchip symbols for drm driver. INFO: 1 function symbol(s) added 'unsigned int drm_format_info_bpp(const struct drm_format_info*, int)' Bug: 300024866 Signed-off-by: Bian Jin chen Change-Id: I54c9645f16633bb61f1b8b80523e83a07d9c4a4f --- android/abi_gki_aarch64.stg | 10 ++++++++++ android/abi_gki_aarch64_rockchip | 1 + 2 files changed, 11 insertions(+) diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index 8b8d8fa00212..2a333ca339c1 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -371199,6 +371199,15 @@ elf_symbol { type_id: 0xc21e59d8 full_name: "drm_format_info_block_width" } +elf_symbol { + id: 0xe946576f + name: "drm_format_info_bpp" + is_defined: true + symbol_type: FUNCTION + crc: 0xe633a4cd + type_id: 0xc21e59d8 + full_name: "drm_format_info_bpp" +} elf_symbol { id: 0x4b9e6227 name: "drm_format_info_min_pitch" @@ -421142,6 +421151,7 @@ interface { symbol_id: 0xaad93a6e symbol_id: 0x820af79e symbol_id: 0xf5a866d4 + symbol_id: 0xe946576f symbol_id: 0x4b9e6227 symbol_id: 0x9c6b68f2 symbol_id: 0x8ab89d74 diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index ed1693df7d00..073aecdd5ae1 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -2522,6 +2522,7 @@ drm_flip_work_init drm_flip_work_queue drm_format_info + drm_format_info_bpp drm_format_info_min_pitch drm_framebuffer_cleanup drm_framebuffer_init