diff --git a/OWNERS_DrNo b/OWNERS_DrNo deleted file mode 100644 index c4b8c0d5e270..000000000000 --- a/OWNERS_DrNo +++ /dev/null @@ -1,23 +0,0 @@ -# Authoritative list of Dr. No reviewers to approve changes on GKI release -# branches, such as android12-5.10. -# -# This file has no effect in this branch, but is referred to from release -# branches. So, please do not move or rename. -# -# See the GKI release documentation (go/gki-dr-no) for further details. - -# Main reviewers -adelva@google.com -maennich@google.com -saravanak@google.com -vmartensson@google.com -tkjos@google.com -willdeacon@google.com - -# GKI Release Team -howardsoc@google.com #{LAST_RESORT_SUGGESTION} -szuweilin@google.com #{LAST_RESORT_SUGGESTION} - -# Backup -sspatil@google.com #{LAST_RESORT_SUGGESTION} -malchev@google.com #{LAST_RESORT_SUGGESTION} diff --git a/android/abi_gki_aarch64.stg b/android/abi_gki_aarch64.stg index f9ec60375ec5..2baf70fbdb50 100644 --- a/android/abi_gki_aarch64.stg +++ b/android/abi_gki_aarch64.stg @@ -5148,6 +5148,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x1c3eec85 } +pointer_reference { + id: 0x0d9fa351 + kind: POINTER + pointee_type_id: 0x1c3e6bd8 +} pointer_reference { id: 0x0da01896 kind: POINTER @@ -5458,6 +5463,16 @@ pointer_reference { kind: POINTER pointee_type_id: 0x1d33ca38 } +pointer_reference { + id: 0x0ddd9122 + kind: POINTER + pointee_type_id: 0x1d36a215 +} +pointer_reference { + id: 0x0dddbb92 + kind: POINTER + pointee_type_id: 0x1d3608d6 +} pointer_reference { id: 0x0dde65b8 kind: POINTER @@ -14183,6 +14198,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x9a8049e0 } +pointer_reference { + id: 0x2c302ca8 + kind: POINTER + pointee_type_id: 0x9a80543f +} pointer_reference { id: 0x2c312b62 kind: POINTER @@ -20043,6 +20063,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0x903e851b } +pointer_reference { + id: 0x2e9fb2c1 + kind: POINTER + pointee_type_id: 0x903e2d98 +} pointer_reference { id: 0x2e9fe637 kind: POINTER @@ -24743,6 +24768,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xf9fcb2cf } +pointer_reference { + id: 0x34f747ff + kind: POINTER + pointee_type_id: 0xf99df961 +} pointer_reference { id: 0x3500e23a kind: POINTER @@ -26583,6 +26613,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xc8994ffb } +pointer_reference { + id: 0x38bb4688 + kind: POINTER + pointee_type_id: 0xc8adfcbd +} pointer_reference { id: 0x38bc670e kind: POINTER @@ -27858,6 +27893,11 @@ pointer_reference { kind: POINTER pointee_type_id: 0xc50f0744 } +pointer_reference { + id: 0x3bd482ed + kind: POINTER + pointee_type_id: 0xc512ed2b +} pointer_reference { id: 0x3bd6fa3a kind: POINTER @@ -32183,6 +32223,11 @@ qualified { qualifier: CONST qualified_type_id: 0x639c2545 } +qualified { + id: 0xc512ed2b + qualifier: CONST + qualified_type_id: 0x640c0226 +} qualified { id: 0xc5274ab2 qualifier: CONST @@ -35063,6 +35108,11 @@ qualified { qualifier: CONST qualified_type_id: 0x95a5decf } +qualified { + id: 0xf99df961 + qualifier: CONST + qualified_type_id: 0x9630530f +} qualified { id: 0xf9d1a7a0 qualifier: CONST @@ -44204,6 +44254,12 @@ member { type_id: 0x2c7e659b offset: 1152 } +member { + id: 0xfdc15727 + name: "add_port" + type_id: 0x0d9fa351 + offset: 128 +} member { id: 0x4dcf2c11 name: "add_producer" @@ -73090,6 +73146,12 @@ member { type_id: 0x0fa14b4c offset: 320 } +member { + id: 0x702151a1 + name: "del_port" + type_id: 0x0d9fa351 + offset: 192 +} member { id: 0x5e7ee5d3 name: "del_producer" @@ -80843,6 +80905,12 @@ member { type_id: 0x33756485 offset: 192 } +member { + id: 0xa072eefa + name: "dump_size" + type_id: 0x2c302ca8 + offset: 320 +} member { id: 0x031e119e name: "dump_stats" @@ -80867,6 +80935,12 @@ member { type_id: 0x0d21fdc9 offset: 1856 } +member { + id: 0x4cc2c45a + name: "dump_write" + type_id: 0x2e9fb2c1 + offset: 384 +} member { id: 0xfc3fad02 name: "dumper" @@ -96734,6 +96808,11 @@ member { type_id: 0x2ced7c4b offset: 1536 } +member { + id: 0x06a833a8 + name: "get_port" + type_id: 0x0ddd9122 +} member { id: 0xa9079cd6 name: "get_power_status" @@ -165802,6 +165881,12 @@ member { type_id: 0x629984b1 offset: 25984 } +member { + id: 0x7062211d + name: "reset_ntf" + type_id: 0x0d9c4ffe + offset: 256 +} member { id: 0x98c83941 name: "reset_pending" @@ -175535,6 +175620,12 @@ member { name: "set_port" type_id: 0x2e9bbd8d } +member { + id: 0x9a820b0d + name: "set_port_priv" + type_id: 0x0dddbb92 + offset: 64 +} member { id: 0x8086060a name: "set_power" @@ -262973,6 +263064,21 @@ struct_union { member_id: 0xb0bb615b } } +struct_union { + id: 0x9630530f + kind: STRUCT + name: "udp_tunnel_nic_ops" + definition { + bytesize: 56 + member_id: 0x06a833a8 + member_id: 0x9a820b0d + member_id: 0xfdc15727 + member_id: 0x702151a1 + member_id: 0x7062211d + member_id: 0xa072eefa + member_id: 0x4cc2c45a + } +} struct_union { id: 0xe832fb84 kind: STRUCT @@ -292685,6 +292791,12 @@ function { return_type_id: 0x48b5725f parameter_id: 0x126add1c } +function { + id: 0x140332fd + return_type_id: 0x48b5725f + parameter_id: 0x13580d6c + parameter_id: 0x13580d6c +} function { id: 0x140db9fc return_type_id: 0x48b5725f @@ -297707,6 +297819,12 @@ function { return_type_id: 0x48b5725f parameter_id: 0x32941b2b } +function { + id: 0x1c3e6bd8 + return_type_id: 0x48b5725f + parameter_id: 0x32a623d7 + parameter_id: 0x03ecaf94 +} function { id: 0x1c3eec85 return_type_id: 0x48b5725f @@ -298537,6 +298655,22 @@ function { parameter_id: 0x0258f96e parameter_id: 0x32bd639f } +function { + id: 0x1d3608d6 + return_type_id: 0x48b5725f + parameter_id: 0x32a623d7 + parameter_id: 0x4585663f + parameter_id: 0x4585663f + parameter_id: 0x295c7202 +} +function { + id: 0x1d36a215 + return_type_id: 0x48b5725f + parameter_id: 0x32a623d7 + parameter_id: 0x4585663f + parameter_id: 0x4585663f + parameter_id: 0x03ecaf94 +} function { id: 0x1d39707c return_type_id: 0x48b5725f @@ -299536,6 +299670,12 @@ function { return_type_id: 0x48b5725f parameter_id: 0x3863a91c } +function { + id: 0x1e818bd6 + return_type_id: 0x48b5725f + parameter_id: 0x3c3f3f74 + parameter_id: 0x4585663f +} function { id: 0x1e82fda2 return_type_id: 0x48b5725f @@ -299707,6 +299847,11 @@ function { parameter_id: 0x6d7f5ff6 parameter_id: 0x6d7f5ff6 } +function { + id: 0x1eb68031 + return_type_id: 0x48b5725f + parameter_id: 0x38bb4688 +} function { id: 0x1eb74850 return_type_id: 0x48b5725f @@ -300506,6 +300651,11 @@ function { return_type_id: 0x48b5725f parameter_id: 0x3c2dd1ca } +function { + id: 0x1f979e4e + return_type_id: 0x48b5725f + parameter_id: 0x3c3f3f74 +} function { id: 0x1f97abfa return_type_id: 0x48b5725f @@ -301542,6 +301692,13 @@ function { return_type_id: 0x27b71910 parameter_id: 0x1d44326e } +function { + id: 0x30d98140 + return_type_id: 0x0483e6f8 + parameter_id: 0x3bb11c92 + parameter_id: 0x0483e6f8 + parameter_id: 0x6720d32f +} function { id: 0x30dc6fbb return_type_id: 0x17dabdcd @@ -305409,6 +305566,11 @@ function { parameter_id: 0x3a6574c9 parameter_id: 0x3bad809b } +function { + id: 0x733f53a5 + return_type_id: 0x309d6e18 + parameter_id: 0x3e10b518 +} function { id: 0x73531faf return_type_id: 0x92233392 @@ -306192,6 +306354,14 @@ function { parameter_id: 0x6720d32f parameter_id: 0x390b641d } +function { + id: 0x84ad5b06 + return_type_id: 0x6720d32f + parameter_id: 0x6720d32f + parameter_id: 0x38264f07 + parameter_id: 0x1d19a9d5 + parameter_id: 0x94ed3026 +} function { id: 0x84af08b2 return_type_id: 0x6720d32f @@ -307154,6 +307324,13 @@ function { parameter_id: 0x3411dbb1 parameter_id: 0x2e0f9112 } +function { + id: 0x903e2d98 + return_type_id: 0x6720d32f + parameter_id: 0x32a623d7 + parameter_id: 0x4585663f + parameter_id: 0x054f691a +} function { id: 0x903e8010 return_type_id: 0x6720d32f @@ -308694,6 +308871,12 @@ function { parameter_id: 0x32a623d7 parameter_id: 0x282d39ce } +function { + id: 0x918c1a12 + return_type_id: 0x6720d32f + parameter_id: 0x32a623d7 + parameter_id: 0x295c7202 +} function { id: 0x918cb258 return_type_id: 0x6720d32f @@ -308907,6 +309090,14 @@ function { parameter_id: 0x2a48f3d0 parameter_id: 0x4585663f } +function { + id: 0x91aa0c4b + return_type_id: 0x6720d32f + parameter_id: 0x32a623d7 + parameter_id: 0x295c7202 + parameter_id: 0x914dbfdc + parameter_id: 0x914dbfdc +} function { id: 0x91aa9fd5 return_type_id: 0x6720d32f @@ -310300,6 +310491,11 @@ function { parameter_id: 0xc9082b19 parameter_id: 0x07dcdbe1 } +function { + id: 0x926a291d + return_type_id: 0x6720d32f + parameter_id: 0x3fab28c8 +} function { id: 0x926bbb17 return_type_id: 0x6720d32f @@ -310525,6 +310721,11 @@ function { return_type_id: 0x6720d32f parameter_id: 0x3c3fe9a7 } +function { + id: 0x928f2cf2 + return_type_id: 0x6720d32f + parameter_id: 0x3c3f3f74 +} function { id: 0x9291a5ba return_type_id: 0x3e10b518 @@ -311482,6 +311683,13 @@ function { parameter_id: 0x391e6bd6 parameter_id: 0x3e10b518 } +function { + id: 0x934097b0 + return_type_id: 0x6720d32f + parameter_id: 0x38bb4688 + parameter_id: 0x3bd482ed + parameter_id: 0x07dcdbe1 +} function { id: 0x9340e134 return_type_id: 0x6720d32f @@ -311858,6 +312066,12 @@ function { parameter_id: 0x3806390a parameter_id: 0x0665e6b6 } +function { + id: 0x9399396a + return_type_id: 0x6720d32f + parameter_id: 0x3c3f3f74 + parameter_id: 0x4585663f +} function { id: 0x93994651 return_type_id: 0x11c404ba @@ -317502,6 +317716,11 @@ function { parameter_id: 0x1e870478 parameter_id: 0xf017819f } +function { + id: 0x99e386dd + return_type_id: 0x6720d32f + parameter_id: 0x118d97cb +} function { id: 0x99e4a009 return_type_id: 0x6720d32f @@ -318447,6 +318666,12 @@ function { parameter_id: 0x1d44326e parameter_id: 0x1469952b } +function { + id: 0x9a80543f + return_type_id: 0xf435685e + parameter_id: 0x32a623d7 + parameter_id: 0x4585663f +} function { id: 0x9a844b16 return_type_id: 0x6720d32f @@ -321887,6 +322112,12 @@ function { parameter_id: 0x11cffa09 parameter_id: 0x92233392 } +function { + id: 0x9bbc7443 + return_type_id: 0x6720d32f + parameter_id: 0x11e6864c + parameter_id: 0x914dbfdc +} function { id: 0x9bbcaaf0 return_type_id: 0x6720d32f @@ -327635,6 +327866,18 @@ function { parameter_id: 0xc9082b19 parameter_id: 0x07dcdbe1 } +function { + id: 0x9e8d7e28 + return_type_id: 0x6720d32f + parameter_id: 0x0ca27481 + parameter_id: 0x09451098 + parameter_id: 0x0277bf8a + parameter_id: 0x239e18b5 + parameter_id: 0x1393392e + parameter_id: 0xc9082b19 + parameter_id: 0xc9082b19 + parameter_id: 0x07dcdbe1 +} function { id: 0x9e8fd7cb return_type_id: 0x6720d32f @@ -333804,6 +334047,11 @@ function { return_type_id: 0x1729da91 parameter_id: 0x1e9745d3 } +function { + id: 0xf869eaec + return_type_id: 0x6d7f5ff6 + parameter_id: 0x1b36c7a2 +} function { id: 0xf879ffed return_type_id: 0x0b59f310 @@ -336968,6 +337216,15 @@ elf_symbol { type_id: 0x026c1696 full_name: "__of_reset_control_get" } +elf_symbol { + id: 0x4b944f82 + name: "__oom_reap_task_mm" + is_defined: true + symbol_type: FUNCTION + crc: 0xefd8a66d + type_id: 0xf869eaec + full_name: "__oom_reap_task_mm" +} elf_symbol { id: 0x4d1e5aba name: "__page_file_index" @@ -338363,6 +338620,15 @@ elf_symbol { type_id: 0x9bc253cf full_name: "__traceiter_android_rvh_is_cpu_allowed" } +elf_symbol { + id: 0xed2646da + name: "__traceiter_android_rvh_meminfo_proc_show" + is_defined: true + symbol_type: FUNCTION + crc: 0x92ecc686 + type_id: 0x9bb62df9 + full_name: "__traceiter_android_rvh_meminfo_proc_show" +} elf_symbol { id: 0x1ea5d323 name: "__traceiter_android_rvh_migrate_queued_task" @@ -342584,6 +342850,15 @@ elf_symbol { type_id: 0x18ccbd2c full_name: "__tracepoint_android_rvh_is_cpu_allowed" } +elf_symbol { + id: 0x2252c1f0 + name: "__tracepoint_android_rvh_meminfo_proc_show" + is_defined: true + symbol_type: OBJECT + crc: 0x0894f789 + type_id: 0x18ccbd2c + full_name: "__tracepoint_android_rvh_meminfo_proc_show" +} elf_symbol { id: 0x3cb4db49 name: "__tracepoint_android_rvh_migrate_queued_task" @@ -347901,6 +348176,15 @@ elf_symbol { type_id: 0x1e18ac15 full_name: "avenrun" } +elf_symbol { + id: 0x0760f21e + name: "backlight_device_get_by_name" + is_defined: true + symbol_type: FUNCTION + crc: 0xbdffe5b8 + type_id: 0x733f53a5 + full_name: "backlight_device_get_by_name" +} elf_symbol { id: 0xb9c34cbd name: "backlight_device_get_by_type" @@ -352071,6 +352355,15 @@ elf_symbol { type_id: 0xd0d5f663 full_name: "cpu_bit_bitmap" } +elf_symbol { + id: 0xb8669175 + name: "cpu_busy_with_softirqs" + is_defined: true + symbol_type: FUNCTION + crc: 0x3c5aab9e + type_id: 0xe76c6fcf + full_name: "cpu_busy_with_softirqs" +} elf_symbol { id: 0x15e1667b name: "cpu_have_feature" @@ -354220,6 +354513,15 @@ elf_symbol { type_id: 0x1f15d172 full_name: "delayed_work_timer_fn" } +elf_symbol { + id: 0x431b7cda + name: "dentry_path_raw" + is_defined: true + symbol_type: FUNCTION + crc: 0xa4942c22 + type_id: 0x30d98140 + full_name: "dentry_path_raw" +} elf_symbol { id: 0x1ef313dc name: "des_expand_key" @@ -358830,6 +359132,15 @@ elf_symbol { type_id: 0x1b27f18a full_name: "do_SAK" } +elf_symbol { + id: 0x9c1c9dfa + name: "do_send_sig_info" + is_defined: true + symbol_type: FUNCTION + crc: 0x4a95e76f + type_id: 0x84ad5b06 + full_name: "do_send_sig_info" +} elf_symbol { id: 0xb50c088c name: "do_trace_netlink_extack" @@ -364725,6 +365036,15 @@ elf_symbol { type_id: 0x96b04c18 full_name: "fs_param_is_u32" } +elf_symbol { + id: 0xbc2aa09b + name: "fscrypt_file_open" + is_defined: true + symbol_type: FUNCTION + crc: 0x54e4c19d + type_id: 0x9b022eae + full_name: "fscrypt_file_open" +} elf_symbol { id: 0x196ad62a name: "fsg_common_create_luns" @@ -365987,6 +366307,15 @@ elf_symbol { type_id: 0x534abe77 full_name: "get_random_u8" } +elf_symbol { + id: 0x7aac3cd4 + name: "get_reclaim_params" + is_defined: true + symbol_type: FUNCTION + crc: 0x14d5a025 + type_id: 0x140332fd + full_name: "get_reclaim_params" +} elf_symbol { id: 0x3a06dd48 name: "get_sg_io_hdr" @@ -376281,6 +376610,15 @@ elf_symbol { type_id: 0x1fdf0b41 full_name: "netdev_printk" } +elf_symbol { + id: 0x6c3e8f78 + name: "netdev_reset_tc" + is_defined: true + symbol_type: FUNCTION + crc: 0x13ed0551 + type_id: 0x1c31d966 + full_name: "netdev_reset_tc" +} elf_symbol { id: 0x22c60050 name: "netdev_rss_key_fill" @@ -376317,6 +376655,24 @@ elf_symbol { type_id: 0x1cd08481 full_name: "netdev_set_default_ethtool_ops" } +elf_symbol { + id: 0xd0f388bf + name: "netdev_set_num_tc" + is_defined: true + symbol_type: FUNCTION + crc: 0x1e03adf1 + type_id: 0x918c1a12 + full_name: "netdev_set_num_tc" +} +elf_symbol { + id: 0xc32be078 + name: "netdev_set_tc_queue" + is_defined: true + symbol_type: FUNCTION + crc: 0x4442f196 + type_id: 0x91aa0c4b + full_name: "netdev_set_tc_queue" +} elf_symbol { id: 0x13d32ab6 name: "netdev_state_change" @@ -380253,6 +380609,15 @@ elf_symbol { type_id: 0x998196f8 full_name: "pci_set_power_state" } +elf_symbol { + id: 0xab90cbbb + name: "pci_sriov_set_totalvfs" + is_defined: true + symbol_type: FUNCTION + crc: 0x32679a37 + type_id: 0x9bbc7443 + full_name: "pci_sriov_set_totalvfs" +} elf_symbol { id: 0xa321b388 name: "pci_stop_root_bus" @@ -388812,6 +389177,15 @@ elf_symbol { type_id: 0xff048ca3 full_name: "set_page_writeback" } +elf_symbol { + id: 0x62e16249 + name: "set_reclaim_params" + is_defined: true + symbol_type: FUNCTION + crc: 0x51ece615 + type_id: 0x85d454a8 + full_name: "set_reclaim_params" +} elf_symbol { id: 0xe19d98a9 name: "set_task_cpu" @@ -390685,6 +391059,15 @@ elf_symbol { type_id: 0x98aeb261 full_name: "snd_pcm_stop_xrun" } +elf_symbol { + id: 0x1fcc9eb7 + name: "snd_pcm_suspend_all" + is_defined: true + symbol_type: FUNCTION + crc: 0x5135cc11 + type_id: 0x99e386dd + full_name: "snd_pcm_suspend_all" +} elf_symbol { id: 0x1f5649eb name: "snd_sgbuf_get_addr" @@ -393982,6 +394365,15 @@ elf_symbol { type_id: 0xf4933b90 full_name: "tasklist_lock" } +elf_symbol { + id: 0xbdf90845 + name: "tc_cleanup_offload_action" + is_defined: true + symbol_type: FUNCTION + crc: 0x17886569 + type_id: 0x1eb68031 + full_name: "tc_cleanup_offload_action" +} elf_symbol { id: 0x1a591d57 name: "tc_setup_cb_add" @@ -394018,6 +394410,15 @@ elf_symbol { type_id: 0x932e1cba full_name: "tc_setup_cb_reoffload" } +elf_symbol { + id: 0x988023d7 + name: "tc_setup_offload_action" + is_defined: true + symbol_type: FUNCTION + crc: 0x77174f16 + type_id: 0x934097b0 + full_name: "tc_setup_offload_action" +} elf_symbol { id: 0xd6059721 name: "tcf_action_check_ctrlact" @@ -394045,6 +394446,15 @@ elf_symbol { type_id: 0xd6fcc6b4 full_name: "tcf_action_set_ctrlact" } +elf_symbol { + id: 0xd4d51230 + name: "tcf_action_update_hw_stats" + is_defined: true + symbol_type: FUNCTION + crc: 0xfb5e97ce + type_id: 0x926a291d + full_name: "tcf_action_update_hw_stats" +} elf_symbol { id: 0x2fba8b59 name: "tcf_action_update_stats" @@ -394117,6 +394527,15 @@ elf_symbol { type_id: 0x9e8d7e1b full_name: "tcf_exts_validate" } +elf_symbol { + id: 0xe0bd8904 + name: "tcf_exts_validate_ex" + is_defined: true + symbol_type: FUNCTION + crc: 0x623630cd + type_id: 0x9e8d7e28 + full_name: "tcf_exts_validate_ex" +} elf_symbol { id: 0x15d83074 name: "tcf_generic_walker" @@ -396745,6 +397164,15 @@ elf_symbol { type_id: 0x99621666 full_name: "udp_tunnel6_xmit_skb" } +elf_symbol { + id: 0x7d720277 + name: "udp_tunnel_nic_ops" + is_defined: true + symbol_type: OBJECT + crc: 0x5f62b5af + type_id: 0x34f747ff + full_name: "udp_tunnel_nic_ops" +} elf_symbol { id: 0x7f7d27b4 name: "udp_tunnel_sock_release" @@ -403702,6 +404130,24 @@ elf_symbol { type_id: 0x9fdeaef3 full_name: "xt_register_match" } +elf_symbol { + id: 0xb2fbe60e + name: "xt_register_target" + is_defined: true + symbol_type: FUNCTION + crc: 0x52ab20be + type_id: 0x928f2cf2 + full_name: "xt_register_target" +} +elf_symbol { + id: 0x450f3768 + name: "xt_register_targets" + is_defined: true + symbol_type: FUNCTION + crc: 0xd5418617 + type_id: 0x9399396a + full_name: "xt_register_targets" +} elf_symbol { id: 0xffcb0fa2 name: "xt_request_find_match" @@ -403729,6 +404175,24 @@ elf_symbol { type_id: 0x12c61c4f full_name: "xt_unregister_match" } +elf_symbol { + id: 0x15f1eb71 + name: "xt_unregister_target" + is_defined: true + symbol_type: FUNCTION + crc: 0xd16885ed + type_id: 0x1f979e4e + full_name: "xt_unregister_target" +} +elf_symbol { + id: 0x7c598ee8 + name: "xt_unregister_targets" + is_defined: true + symbol_type: FUNCTION + crc: 0x621efe3e + type_id: 0x1e818bd6 + full_name: "xt_unregister_targets" +} elf_symbol { id: 0x0fc8c78d name: "zap_vma_ptes" @@ -404199,6 +404663,7 @@ interface { symbol_id: 0x38c74e33 symbol_id: 0xcbeef20f symbol_id: 0x10e977be + symbol_id: 0x4b944f82 symbol_id: 0x4d1e5aba symbol_id: 0x057c7766 symbol_id: 0x8d43f7e0 @@ -404354,6 +404819,7 @@ interface { symbol_id: 0xfc83b254 symbol_id: 0x7e99bc71 symbol_id: 0x7c212080 + symbol_id: 0xed2646da symbol_id: 0x1ea5d323 symbol_id: 0xc1a482d8 symbol_id: 0x9c17d92b @@ -404823,6 +405289,7 @@ interface { symbol_id: 0x4fd98142 symbol_id: 0x695c4baf symbol_id: 0x99d57c12 + symbol_id: 0x2252c1f0 symbol_id: 0x3cb4db49 symbol_id: 0x3a6f3fb2 symbol_id: 0x8b0b932d @@ -405414,6 +405881,7 @@ interface { symbol_id: 0xd772fde3 symbol_id: 0x1abdc14f symbol_id: 0x3eb51b20 + symbol_id: 0x0760f21e symbol_id: 0xb9c34cbd symbol_id: 0x0bd7f049 symbol_id: 0xf54175ef @@ -405878,6 +406346,7 @@ interface { symbol_id: 0x9f1f7cee symbol_id: 0xd89255c2 symbol_id: 0x962b6a68 + symbol_id: 0xb8669175 symbol_id: 0x15e1667b symbol_id: 0x33bbeca6 symbol_id: 0x4e0ae383 @@ -406117,6 +406586,7 @@ interface { symbol_id: 0xf666562b symbol_id: 0xa5179b7b symbol_id: 0xc1583575 + symbol_id: 0x431b7cda symbol_id: 0x1ef313dc symbol_id: 0x67daf3cf symbol_id: 0xe5161e20 @@ -406627,6 +407097,7 @@ interface { symbol_id: 0x400fac71 symbol_id: 0xdae2cdaf symbol_id: 0x6bebb14a + symbol_id: 0x9c1c9dfa symbol_id: 0xb50c088c symbol_id: 0xae435551 symbol_id: 0x718fec30 @@ -407282,6 +407753,7 @@ interface { symbol_id: 0x9a2423a0 symbol_id: 0x6c9f28bc symbol_id: 0x35a180e7 + symbol_id: 0xbc2aa09b symbol_id: 0x196ad62a symbol_id: 0x804c5038 symbol_id: 0x07715f1a @@ -407422,6 +407894,7 @@ interface { symbol_id: 0x0447d62c symbol_id: 0xba2bc2c4 symbol_id: 0x3266d1f2 + symbol_id: 0x7aac3cd4 symbol_id: 0x3a06dd48 symbol_id: 0x75d8e345 symbol_id: 0xfa5debf3 @@ -408566,10 +409039,13 @@ interface { symbol_id: 0xd5ed1a09 symbol_id: 0xd78c295f symbol_id: 0xe42df14f + symbol_id: 0x6c3e8f78 symbol_id: 0x22c60050 symbol_id: 0x7a3d8713 symbol_id: 0xf7edefd1 symbol_id: 0xb78d7b09 + symbol_id: 0xd0f388bf + symbol_id: 0xc32be078 symbol_id: 0x13d32ab6 symbol_id: 0x88a6525c symbol_id: 0xa9b870ab @@ -409007,6 +409483,7 @@ interface { symbol_id: 0x9595d229 symbol_id: 0xfc86cde9 symbol_id: 0xe770d8d1 + symbol_id: 0xab90cbbb symbol_id: 0xa321b388 symbol_id: 0x958eb206 symbol_id: 0xd0c1e622 @@ -409958,6 +410435,7 @@ interface { symbol_id: 0x455375fa symbol_id: 0xc1ea8aaa symbol_id: 0x500f328c + symbol_id: 0x62e16249 symbol_id: 0xe19d98a9 symbol_id: 0xdebcf3e9 symbol_id: 0x8f1deac6 @@ -410166,6 +410644,7 @@ interface { symbol_id: 0xb2f7eb17 symbol_id: 0x8eb5b50d symbol_id: 0xc26d0753 + symbol_id: 0x1fcc9eb7 symbol_id: 0x1f5649eb symbol_id: 0x31ef5894 symbol_id: 0xf19e02b6 @@ -410533,13 +411012,16 @@ interface { symbol_id: 0x9c77d018 symbol_id: 0x9b3fb280 symbol_id: 0x6c3c9573 + symbol_id: 0xbdf90845 symbol_id: 0x1a591d57 symbol_id: 0xf099d343 symbol_id: 0xadb59b05 symbol_id: 0xbfd2d0d2 + symbol_id: 0x988023d7 symbol_id: 0xd6059721 symbol_id: 0x01cdd14d symbol_id: 0x2d797653 + symbol_id: 0xd4d51230 symbol_id: 0x2fba8b59 symbol_id: 0xcda1c9b0 symbol_id: 0xc924b9c3 @@ -410548,6 +411030,7 @@ interface { symbol_id: 0xcc0525bc symbol_id: 0xb8aeb338 symbol_id: 0xd6adc7e6 + symbol_id: 0xe0bd8904 symbol_id: 0x15d83074 symbol_id: 0x199994d8 symbol_id: 0xf8fc1781 @@ -410840,6 +411323,7 @@ interface { symbol_id: 0x2259ac6a symbol_id: 0x3bea1d77 symbol_id: 0x83627eaa + symbol_id: 0x7d720277 symbol_id: 0x7f7d27b4 symbol_id: 0x674efb6f symbol_id: 0x3fa12248 @@ -411613,9 +412097,13 @@ interface { symbol_id: 0x8eb67e0f symbol_id: 0xf6d0be30 symbol_id: 0x7a3f2cd6 + symbol_id: 0xb2fbe60e + symbol_id: 0x450f3768 symbol_id: 0xffcb0fa2 symbol_id: 0xa2ee5f12 symbol_id: 0x807b9318 + symbol_id: 0x15f1eb71 + symbol_id: 0x7c598ee8 symbol_id: 0x0fc8c78d symbol_id: 0xe8e0ea6a symbol_id: 0xa5d58813 diff --git a/android/abi_gki_aarch64_honda b/android/abi_gki_aarch64_honda index 8ee57762f944..4153b8ae27e9 100644 --- a/android/abi_gki_aarch64_honda +++ b/android/abi_gki_aarch64_honda @@ -23,12 +23,16 @@ skb_flow_dissect_meta skb_flow_dissect_tunnel_info skb_flow_dissector_init + tc_cleanup_offload_action tc_setup_cb_call tc_setup_cb_destroy tc_setup_cb_reoffload tc_setup_cb_add + tc_setup_offload_action + tcf_action_update_hw_stats tcf_exts_num_actions tcf_exts_terse_dump + tcf_exts_validate_ex # required by act_vlan.ko module jiffies_to_clock_t @@ -69,8 +73,14 @@ xt_compat_unlock xt_data_to_user xt_find_match + xt_register_target xt_request_find_match xt_request_find_target + xt_unregister_target + +# commonly required by ebt_*.ko modules + xt_register_match + xt_unregister_match # required by ebt_arpreply.ko module arp_send @@ -89,3 +99,8 @@ nf_log_unset nf_logger_find_get nf_logger_put + xt_register_targets + xt_unregister_targets + +# required by audio related modules + snd_pcm_suspend_all diff --git a/android/abi_gki_aarch64_nothing b/android/abi_gki_aarch64_nothing index ae40328eb56b..2a1b010e4b86 100644 --- a/android/abi_gki_aarch64_nothing +++ b/android/abi_gki_aarch64_nothing @@ -42,6 +42,7 @@ create_empty_buffers current_time current_umask + dentry_path_raw d_find_alias d_instantiate discard_new_inode @@ -69,6 +70,7 @@ __folio_lock __folio_put fs_bio_set + fscrypt_file_open fs_param_is_string fs_param_is_u32 __fs_parse diff --git a/android/abi_gki_aarch64_pixel b/android/abi_gki_aarch64_pixel index 9ef39dbbe259..fe4e815bf551 100644 --- a/android/abi_gki_aarch64_pixel +++ b/android/abi_gki_aarch64_pixel @@ -24,6 +24,7 @@ __alloc_skb alloc_skb_with_frags alloc_workqueue + all_vm_events alt_cb_patch_nops amba_bustype amba_driver_register @@ -230,6 +231,7 @@ __cpu_active_mask cpu_all_bits cpu_bit_bitmap + cpu_busy_with_softirqs cpufreq_add_update_util_hook cpufreq_cpu_get cpufreq_cpu_get_raw @@ -610,6 +612,7 @@ dma_unmap_resource dma_unmap_sg_attrs do_SAK + do_send_sig_info do_trace_netlink_extack do_wait_intr_irq down @@ -979,6 +982,7 @@ get_random_u32 __get_random_u32_below get_random_u8 + get_reclaim_params get_sg_io_hdr __get_task_comm get_task_cred @@ -1260,6 +1264,7 @@ kobj_sysfs_ops krealloc ksize + ksoftirqd kstat kstrdup kstrndup @@ -1551,6 +1556,7 @@ of_thermal_is_trip_valid of_translate_address of_usb_host_tpl_support + __oom_reap_task_mm page_endio page_frag_alloc_align __page_frag_cache_drain @@ -1562,6 +1568,7 @@ param_array_ops param_get_int param_get_string + param_get_uint param_ops_bool param_ops_byte param_ops_charp @@ -1572,6 +1579,7 @@ param_ops_ulong param_set_copystring param_set_int + param_set_uint pci_alloc_irq_vectors_affinity pci_assign_resource pci_clear_master @@ -1609,6 +1617,7 @@ pci_wake_from_d3 pci_write_config_dword pci_write_config_word + pcpu_nr_pages __per_cpu_offset perf_aux_output_begin perf_aux_output_end @@ -1747,6 +1756,10 @@ put_unused_fd put_vaddr_frames pwm_apply_state + pwmchip_add + pwmchip_remove + pwm_get_chip_data + pwm_set_chip_data queue_delayed_work_on queue_work_on radix_tree_delete_item @@ -1933,6 +1946,7 @@ sched_uclamp_used schedule schedule_timeout + schedule_timeout_idle schedule_timeout_interruptible scnprintf scsi_add_host_with_dma @@ -1983,6 +1997,7 @@ set_page_dirty set_page_dirty_lock __SetPageMovable + set_reclaim_params set_task_cpu set_user_nice sg_alloc_table @@ -2001,6 +2016,7 @@ __sg_page_iter_start sg_pcopy_from_buffer shmem_file_setup + si_meminfo simple_attr_open simple_attr_read simple_attr_release @@ -2316,6 +2332,7 @@ __traceiter_android_rvh_iommu_limit_align_shift __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable + __traceiter_android_rvh_meminfo_proc_show __traceiter_android_rvh_post_init_entity_util_avg __traceiter_android_rvh_preempt_disable __traceiter_android_rvh_preempt_enable @@ -2332,6 +2349,7 @@ __traceiter_android_rvh_set_task_cpu __traceiter_android_rvh_set_user_nice __traceiter_android_rvh_set_user_nice_locked + __traceiter_android_rvh_tick_entry __traceiter_android_rvh_typec_tcpci_get_vbus __traceiter_android_rvh_uclamp_eff_get __traceiter_android_rvh_ufs_complete_init @@ -2438,6 +2456,7 @@ __tracepoint_android_rvh_iommu_limit_align_shift __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable + __tracepoint_android_rvh_meminfo_proc_show __tracepoint_android_rvh_post_init_entity_util_avg __tracepoint_android_rvh_preempt_disable __tracepoint_android_rvh_preempt_enable @@ -2454,6 +2473,7 @@ __tracepoint_android_rvh_set_task_cpu __tracepoint_android_rvh_set_user_nice __tracepoint_android_rvh_set_user_nice_locked + __tracepoint_android_rvh_tick_entry __tracepoint_android_rvh_typec_tcpci_get_vbus __tracepoint_android_rvh_uclamp_eff_get __tracepoint_android_rvh_ufs_complete_init @@ -2746,11 +2766,14 @@ virtqueue_kick_prepare virtqueue_notify vmalloc + vmalloc_nr_pages vmalloc_to_page vmalloc_user vmap vmf_insert_pfn_prot vm_iomap_memory + vm_node_stat + vm_zone_stat vprintk vprintk_emit vring_del_virtqueue diff --git a/android/abi_gki_aarch64_virtual_device b/android/abi_gki_aarch64_virtual_device index 7b5c972bff09..eacbf9364c9d 100644 --- a/android/abi_gki_aarch64_virtual_device +++ b/android/abi_gki_aarch64_virtual_device @@ -1349,6 +1349,9 @@ snd_card_free snd_card_new snd_card_register + snd_ctl_add + snd_ctl_new1 + snd_ctl_notify snd_jack_new snd_jack_report snd_pcm_add_chmap_ctls diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index 60c623ce7db0..63104d8e367e 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -301,8 +301,9 @@ of_node_name_prefix bdi_unregister -#required by dispaly.ko +#required by msm_drm.ko mipi_dsi_dcs_set_display_off + backlight_device_get_by_name #required by debug_ext.ko of_find_all_nodes @@ -359,3 +360,14 @@ #required by speed_ui.ko __tracepoint_android_rvh_update_cpus_allowed __traceiter_android_rvh_update_cpus_allowed + +#required by brcm_xgbe.ko + cpumask_local_spread + udp_tunnel_nic_ops + netdev_reset_tc + netdev_set_num_tc + netdev_set_tc_queue + pci_select_bars + pci_sriov_set_totalvfs + pci_num_vf + diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index f83f72e0e820..9322df8ce828 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -237,6 +237,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_v3_affinity_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterrupt_tasks); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_uninterrupt_tasks_done); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_meminfo_proc_show); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_meminfo_proc_show); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 959952e8ede3..e245e8411e15 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -157,6 +157,10 @@ static int g_max_sectors; module_param_named(max_sectors, g_max_sectors, int, 0444); MODULE_PARM_DESC(max_sectors, "Maximum size of a command (in 512B sectors)"); +static unsigned int g_max_segment_size = BLK_MAX_SEGMENT_SIZE; +module_param_named(max_segment_size, g_max_segment_size, int, 0444); +MODULE_PARM_DESC(max_segment_size, "Maximum size of a segment in bytes"); + static unsigned int nr_devices = 1; module_param(nr_devices, uint, 0444); MODULE_PARM_DESC(nr_devices, "Number of devices to register"); @@ -409,6 +413,7 @@ NULLB_DEVICE_ATTR(home_node, uint, NULL); NULLB_DEVICE_ATTR(queue_mode, uint, NULL); NULLB_DEVICE_ATTR(blocksize, uint, NULL); NULLB_DEVICE_ATTR(max_sectors, uint, NULL); +NULLB_DEVICE_ATTR(max_segment_size, uint, NULL); NULLB_DEVICE_ATTR(irqmode, uint, NULL); NULLB_DEVICE_ATTR(hw_queue_depth, uint, NULL); NULLB_DEVICE_ATTR(index, uint, NULL); @@ -532,6 +537,7 @@ static struct configfs_attribute *nullb_device_attrs[] = { &nullb_device_attr_queue_mode, &nullb_device_attr_blocksize, &nullb_device_attr_max_sectors, + &nullb_device_attr_max_segment_size, &nullb_device_attr_irqmode, &nullb_device_attr_hw_queue_depth, &nullb_device_attr_index, @@ -610,7 +616,8 @@ static ssize_t memb_group_features_show(struct config_item *item, char *page) return snprintf(page, PAGE_SIZE, "badblocks,blocking,blocksize,cache_size," "completion_nsec,discard,home_node,hw_queue_depth," - "irqmode,max_sectors,mbps,memory_backed,no_sched," + "irqmode,max_sectors,max_segment_size,mbps," + "memory_backed,no_sched," "poll_queues,power,queue_mode,shared_tag_bitmap,size," "submit_queues,use_per_node_hctx,virt_boundary,zoned," "zone_capacity,zone_max_active,zone_max_open," @@ -673,6 +680,7 @@ static struct nullb_device *null_alloc_dev(void) dev->queue_mode = g_queue_mode; dev->blocksize = g_bs; dev->max_sectors = g_max_sectors; + dev->max_segment_size = g_max_segment_size; dev->irqmode = g_irqmode; dev->hw_queue_depth = g_hw_queue_depth; dev->blocking = g_blocking; @@ -1214,6 +1222,8 @@ static int null_transfer(struct nullb *nullb, struct page *page, unsigned int valid_len = len; int err = 0; + WARN_ONCE(len > dev->max_segment_size, "%u > %u\n", len, + dev->max_segment_size); if (!is_write) { if (dev->zoned) valid_len = null_zone_valid_read_len(nullb, @@ -1249,7 +1259,8 @@ static int null_handle_rq(struct nullb_cmd *cmd) spin_lock_irq(&nullb->lock); rq_for_each_segment(bvec, rq, iter) { - len = bvec.bv_len; + len = min(bvec.bv_len, nullb->dev->max_segment_size); + bvec.bv_len = len; err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset, op_is_write(req_op(rq)), sector, rq->cmd_flags & REQ_FUA); @@ -1276,7 +1287,8 @@ static int null_handle_bio(struct nullb_cmd *cmd) spin_lock_irq(&nullb->lock); bio_for_each_segment(bvec, bio, iter) { - len = bvec.bv_len; + len = min(bvec.bv_len, nullb->dev->max_segment_size); + bvec.bv_len = len; err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset, op_is_write(bio_op(bio)), sector, bio->bi_opf & REQ_FUA); @@ -2116,6 +2128,7 @@ static int null_add_dev(struct nullb_device *dev) blk_queue_physical_block_size(nullb->q, dev->blocksize); if (dev->max_sectors) blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); + blk_queue_max_segment_size(nullb->q, dev->max_segment_size); if (dev->virt_boundary) blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); diff --git a/drivers/block/null_blk/null_blk.h b/drivers/block/null_blk/null_blk.h index 94ff68052b1e..6784ee9f5fda 100644 --- a/drivers/block/null_blk/null_blk.h +++ b/drivers/block/null_blk/null_blk.h @@ -102,6 +102,7 @@ struct nullb_device { unsigned int queue_mode; /* block interface */ unsigned int blocksize; /* block size */ unsigned int max_sectors; /* Max sectors per command */ + unsigned int max_segment_size; /* Max size of a single DMA segment. */ unsigned int irqmode; /* IRQ completion handler */ unsigned int hw_queue_depth; /* queue depth */ unsigned int index; /* index of the disk, only valid with a disk */ diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 53b98d66894a..eeead4566230 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1540,7 +1540,8 @@ static int cpufreq_online(unsigned int cpu) if (cpufreq_driver->ready) cpufreq_driver->ready(policy); - if (cpufreq_thermal_control_enabled(cpufreq_driver)) { + /* Register cpufreq cooling only for a new policy */ + if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver)) { policy->cdev = of_cpufreq_cooling_register(policy); trace_android_vh_thermal_register(policy); } @@ -1626,12 +1627,6 @@ static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy) else policy->last_policy = policy->policy; - if (cpufreq_thermal_control_enabled(cpufreq_driver)) { - cpufreq_cooling_unregister(policy->cdev); - trace_android_vh_thermal_unregister(policy); - policy->cdev = NULL; - } - if (has_target()) cpufreq_exit_governor(policy); @@ -1692,6 +1687,16 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) return; } + /* + * Unregister cpufreq cooling once all the CPUs of the policy are + * removed. + */ + if (cpufreq_thermal_control_enabled(cpufreq_driver)) { + cpufreq_cooling_unregister(policy->cdev); + trace_android_vh_thermal_unregister(policy); + policy->cdev = NULL; + } + /* We did light-weight exit earlier, do full tear down now */ if (cpufreq_driver->offline) cpufreq_driver->exit(policy); diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 78948f4ebb68..9aa216db0f10 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -6167,14 +6167,14 @@ static int tcpm_pd_set(struct typec_port *p, struct usb_power_delivery *pd) if (data->sink_desc.pdo[0]) { for (i = 0; i < PDO_MAX_OBJECTS && data->sink_desc.pdo[i]; i++) port->snk_pdo[i] = data->sink_desc.pdo[i]; - port->nr_snk_pdo = i + 1; + port->nr_snk_pdo = i; port->operating_snk_mw = data->operating_snk_mw; } if (data->source_desc.pdo[0]) { for (i = 0; i < PDO_MAX_OBJECTS && data->source_desc.pdo[i]; i++) port->src_pdo[i] = data->source_desc.pdo[i]; - port->nr_src_pdo = i + 1; + port->nr_src_pdo = i; } switch (port->state) { diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 24a133eb3576..fb82ef502105 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -158,6 +158,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) global_zone_page_state(NR_FREE_CMA_PAGES)); #endif trace_android_vh_meminfo_proc_show(m); + trace_android_rvh_meminfo_proc_show(m); hugetlb_report_meminfo(m); diff --git a/include/linux/gfp.h b/include/linux/gfp.h index e652b9bbb262..9ec3b227e8f2 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -351,6 +351,9 @@ static inline bool pm_suspended_storage(void) } #endif /* CONFIG_PM_SLEEP */ +int set_reclaim_params(int wmark_scale_factor, int swappiness); +void get_reclaim_params(int *wmark_scale_factor, int *swappiness); + #ifdef CONFIG_CONTIG_ALLOC /* The below functions must be run on a range from a single zone. */ extern int alloc_contig_range(unsigned long start, unsigned long end, diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 177547593ee4..cfa532cbd2e8 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -590,7 +590,8 @@ enum #define LONG_SOFTIRQ_MASK (BIT(NET_TX_SOFTIRQ) | \ BIT(NET_RX_SOFTIRQ) | \ BIT(BLOCK_SOFTIRQ) | \ - BIT(IRQ_POLL_SOFTIRQ)) + BIT(IRQ_POLL_SOFTIRQ) | \ + BIT(TASKLET_SOFTIRQ)) /* map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq. diff --git a/include/linux/oom.h b/include/linux/oom.h index f008e23d9b41..1f1aebf17001 100644 --- a/include/linux/oom.h +++ b/include/linux/oom.h @@ -109,6 +109,7 @@ extern int unregister_oom_notifier(struct notifier_block *nb); extern bool oom_killer_disable(signed long timeout); extern void oom_killer_enable(void); +extern bool __oom_reap_task_mm(struct mm_struct *mm); extern struct task_struct *find_lock_task_mm(struct task_struct *p); diff --git a/include/net/tls.h b/include/net/tls.h index 1196d7202f85..8729dd02ec07 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -109,9 +109,6 @@ struct tls_sw_context_tx { struct tls_rec *open_rec; struct list_head tx_list; atomic_t encrypt_pending; - /* protect crypto_wait with encrypt_pending */ - spinlock_t encrypt_compl_lock; - int async_notify; u8 async_capable:1; #define BIT_TX_SCHEDULED 0 @@ -150,8 +147,6 @@ struct tls_sw_context_rx { struct tls_strparser strp; atomic_t decrypt_pending; - /* protect crypto_wait with decrypt_pending*/ - spinlock_t decrypt_compl_lock; struct sk_buff_head async_hold; struct wait_queue_head wq; diff --git a/include/trace/events/oom.h b/include/trace/events/oom.h index 3c5941da8075..b799f3bcba82 100644 --- a/include/trace/events/oom.h +++ b/include/trace/events/oom.h @@ -7,6 +7,8 @@ #include #include +#define PG_COUNT_TO_KB(x) ((x) << (PAGE_SHIFT - 10)) + TRACE_EVENT(oom_score_adj_update, TP_PROTO(struct task_struct *task), @@ -78,22 +80,37 @@ TRACE_EVENT(mark_victim, TP_STRUCT__entry( __field(int, pid) - __field(uid_t, uid) __string(comm, task->comm) + __field(unsigned long, total_vm) + __field(unsigned long, anon_rss) + __field(unsigned long, file_rss) + __field(unsigned long, shmem_rss) + __field(uid_t, uid) + __field(unsigned long, pgtables) __field(short, oom_score_adj) ), TP_fast_assign( __entry->pid = task->pid; - __entry->uid = uid; __assign_str(comm, task->comm); + __entry->total_vm = PG_COUNT_TO_KB(task->mm->total_vm); + __entry->anon_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_ANONPAGES)); + __entry->file_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_FILEPAGES)); + __entry->shmem_rss = PG_COUNT_TO_KB(get_mm_counter(task->mm, MM_SHMEMPAGES)); + __entry->uid = uid; + __entry->pgtables = mm_pgtables_bytes(task->mm) >> 10; __entry->oom_score_adj = task->signal->oom_score_adj; ), - TP_printk("pid=%d uid=%u comm=%s oom_score_adj=%hd", + TP_printk("pid=%d comm=%s total-vm=%lukB anon-rss=%lukB file-rss:%lukB shmem-rss:%lukB uid=%u pgtables=%lukB oom_score_adj=%hd", __entry->pid, - __entry->uid, __get_str(comm), + __entry->total_vm, + __entry->anon_rss, + __entry->file_rss, + __entry->shmem_rss, + __entry->uid, + __entry->pgtables, __entry->oom_score_adj ) ); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 50addc57dc10..28dcf14b9d72 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -60,6 +60,9 @@ DECLARE_HOOK(android_vh_filemap_get_folio, DECLARE_HOOK(android_vh_meminfo_proc_show, TP_PROTO(struct seq_file *m), TP_ARGS(m)); +DECLARE_RESTRICTED_HOOK(android_rvh_meminfo_proc_show, + TP_PROTO(struct seq_file *m), + TP_ARGS(m), 1); DECLARE_HOOK(android_vh_exit_mm, TP_PROTO(struct mm_struct *mm), TP_ARGS(mm)); diff --git a/include/uapi/linux/virtio_snd.h b/include/uapi/linux/virtio_snd.h index dfe49547a7b0..5f4100c2cf04 100644 --- a/include/uapi/linux/virtio_snd.h +++ b/include/uapi/linux/virtio_snd.h @@ -7,6 +7,14 @@ #include +/******************************************************************************* + * FEATURE BITS + */ +enum { + /* device supports control elements */ + VIRTIO_SND_F_CTLS = 0 +}; + /******************************************************************************* * CONFIGURATION SPACE */ @@ -17,6 +25,8 @@ struct virtio_snd_config { __le32 streams; /* # of available channel maps */ __le32 chmaps; + /* # of available control elements */ + __le32 controls; }; enum { @@ -55,6 +65,15 @@ enum { /* channel map control request types */ VIRTIO_SND_R_CHMAP_INFO = 0x0200, + /* control element request types */ + VIRTIO_SND_R_CTL_INFO = 0x0300, + VIRTIO_SND_R_CTL_ENUM_ITEMS, + VIRTIO_SND_R_CTL_READ, + VIRTIO_SND_R_CTL_WRITE, + VIRTIO_SND_R_CTL_TLV_READ, + VIRTIO_SND_R_CTL_TLV_WRITE, + VIRTIO_SND_R_CTL_TLV_COMMAND, + /* jack event types */ VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000, VIRTIO_SND_EVT_JACK_DISCONNECTED, @@ -63,6 +82,9 @@ enum { VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100, VIRTIO_SND_EVT_PCM_XRUN, + /* control element event types */ + VIRTIO_SND_EVT_CTL_NOTIFY = 0x1200, + /* common status codes */ VIRTIO_SND_S_OK = 0x8000, VIRTIO_SND_S_BAD_MSG, @@ -331,4 +353,136 @@ struct virtio_snd_chmap_info { __u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE]; }; +/******************************************************************************* + * CONTROL ELEMENTS MESSAGES + */ +struct virtio_snd_ctl_hdr { + /* VIRTIO_SND_R_CTL_XXX */ + struct virtio_snd_hdr hdr; + /* 0 ... virtio_snd_config::controls - 1 */ + __le32 control_id; +}; + +/* supported roles for control elements */ +enum { + VIRTIO_SND_CTL_ROLE_UNDEFINED = 0, + VIRTIO_SND_CTL_ROLE_VOLUME, + VIRTIO_SND_CTL_ROLE_MUTE, + VIRTIO_SND_CTL_ROLE_GAIN +}; + +/* supported value types for control elements */ +enum { + VIRTIO_SND_CTL_TYPE_BOOLEAN = 0, + VIRTIO_SND_CTL_TYPE_INTEGER, + VIRTIO_SND_CTL_TYPE_INTEGER64, + VIRTIO_SND_CTL_TYPE_ENUMERATED, + VIRTIO_SND_CTL_TYPE_BYTES, + VIRTIO_SND_CTL_TYPE_IEC958 +}; + +/* supported access rights for control elements */ +enum { + VIRTIO_SND_CTL_ACCESS_READ = 0, + VIRTIO_SND_CTL_ACCESS_WRITE, + VIRTIO_SND_CTL_ACCESS_VOLATILE, + VIRTIO_SND_CTL_ACCESS_INACTIVE, + VIRTIO_SND_CTL_ACCESS_TLV_READ, + VIRTIO_SND_CTL_ACCESS_TLV_WRITE, + VIRTIO_SND_CTL_ACCESS_TLV_COMMAND +}; + +struct virtio_snd_ctl_info { + /* common header */ + struct virtio_snd_info hdr; + /* element role (VIRTIO_SND_CTL_ROLE_XXX) */ + __le32 role; + /* element value type (VIRTIO_SND_CTL_TYPE_XXX) */ + __le32 type; + /* element access right bit map (1 << VIRTIO_SND_CTL_ACCESS_XXX) */ + __le32 access; + /* # of members in the element value */ + __le32 count; + /* index for an element with a non-unique name */ + __le32 index; + /* name identifier string for the element */ + __u8 name[44]; + /* additional information about the element's value */ + union { + /* VIRTIO_SND_CTL_TYPE_INTEGER */ + struct { + /* minimum supported value */ + __le32 min; + /* maximum supported value */ + __le32 max; + /* fixed step size for value (0 = variable size) */ + __le32 step; + } integer; + /* VIRTIO_SND_CTL_TYPE_INTEGER64 */ + struct { + /* minimum supported value */ + __le64 min; + /* maximum supported value */ + __le64 max; + /* fixed step size for value (0 = variable size) */ + __le64 step; + } integer64; + /* VIRTIO_SND_CTL_TYPE_ENUMERATED */ + struct { + /* # of options supported for value */ + __le32 items; + } enumerated; + } value; +}; + +struct virtio_snd_ctl_enum_item { + /* option name */ + __u8 item[64]; +}; + +struct virtio_snd_ctl_iec958 { + /* AES/IEC958 channel status bits */ + __u8 status[24]; + /* AES/IEC958 subcode bits */ + __u8 subcode[147]; + /* nothing */ + __u8 pad; + /* AES/IEC958 subframe bits */ + __u8 dig_subframe[4]; +}; + +struct virtio_snd_ctl_value { + union { + /* VIRTIO_SND_CTL_TYPE_BOOLEAN|INTEGER value */ + __le32 integer[128]; + /* VIRTIO_SND_CTL_TYPE_INTEGER64 value */ + __le64 integer64[64]; + /* VIRTIO_SND_CTL_TYPE_ENUMERATED value (option indexes) */ + __le32 enumerated[128]; + /* VIRTIO_SND_CTL_TYPE_BYTES value */ + __u8 bytes[512]; + /* VIRTIO_SND_CTL_TYPE_IEC958 value */ + struct virtio_snd_ctl_iec958 iec958; + } value; +}; + +/* supported event reason types */ +enum { + /* element's value has changed */ + VIRTIO_SND_CTL_EVT_MASK_VALUE = 0, + /* element's information has changed */ + VIRTIO_SND_CTL_EVT_MASK_INFO, + /* element's metadata has changed */ + VIRTIO_SND_CTL_EVT_MASK_TLV +}; + +struct virtio_snd_ctl_event { + /* VIRTIO_SND_EVT_CTL_NOTIFY */ + struct virtio_snd_hdr hdr; + /* 0 ... virtio_snd_config::controls - 1 */ + __le16 control_id; + /* event reason bit map (1 << VIRTIO_SND_CTL_EVT_MASK_XXX) */ + __le16 mask; +}; + #endif /* VIRTIO_SND_IF_H */ diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 2e1e83ff4c80..c0fc24530643 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1636,7 +1636,7 @@ static int find_lowest_rq(struct task_struct *task); * task is likely to block preemptions soon because it is a * ksoftirq thread that is handling softirqs. */ -static bool cpu_busy_with_softirqs(int cpu) +bool cpu_busy_with_softirqs(int cpu) { u32 softirqs = per_cpu(active_softirqs, cpu) | __cpu_softirq_pending(cpu); @@ -1644,11 +1644,12 @@ static bool cpu_busy_with_softirqs(int cpu) return softirqs & LONG_SOFTIRQ_MASK; } #else -static bool cpu_busy_with_softirqs(int cpu) +bool cpu_busy_with_softirqs(int cpu) { return false; } #endif /* CONFIG_RT_SOFTIRQ_AWARE_SCHED */ +EXPORT_SYMBOL_GPL(cpu_busy_with_softirqs); static bool rt_task_fits_cpu(struct task_struct *p, int cpu) { diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 210032735650..f3ee288cc680 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -3278,4 +3278,5 @@ static inline void update_current_exec_runtime(struct task_struct *curr, cgroup_account_cputime(curr, delta_exec); } +extern bool cpu_busy_with_softirqs(int cpu); #endif /* _KERNEL_SCHED_SCHED_H */ diff --git a/kernel/signal.c b/kernel/signal.c index a55cc27959e7..f7a4cfbe24ad 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1312,6 +1312,7 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p return ret; } +EXPORT_SYMBOL_GPL(do_send_sig_info); enum sig_handler { HANDLER_CURRENT, /* If reachable use the current handler */ diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 6bb096462170..7a9e1c7f636c 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -511,7 +511,7 @@ static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait); static struct task_struct *oom_reaper_list; static DEFINE_SPINLOCK(oom_reaper_lock); -static bool __oom_reap_task_mm(struct mm_struct *mm) +bool __oom_reap_task_mm(struct mm_struct *mm) { struct vm_area_struct *vma; bool ret = true; @@ -560,6 +560,7 @@ static bool __oom_reap_task_mm(struct mm_struct *mm) return ret; } +EXPORT_SYMBOL_GPL(__oom_reap_task_mm); /* * Reaps the address space of the give task. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index b88e6ad7eb08..0c32100ecf9a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -536,6 +536,30 @@ static inline int pfn_to_bitidx(const struct page *page, unsigned long pfn) return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS; } +int set_reclaim_params(int wmark_scale_factor, int swappiness) +{ + if (wmark_scale_factor > 3000 || wmark_scale_factor < 1) + return -EINVAL; + + if (swappiness > 200 || swappiness < 0) + return -EINVAL; + + WRITE_ONCE(vm_swappiness, swappiness); + WRITE_ONCE(watermark_scale_factor, wmark_scale_factor); + + setup_per_zone_wmarks(); + + return 0; +} +EXPORT_SYMBOL_GPL(set_reclaim_params); + +void get_reclaim_params(int *wmark_scale_factor, int *swappiness) +{ + *wmark_scale_factor = watermark_scale_factor; + *swappiness = vm_swappiness; +} +EXPORT_SYMBOL_GPL(get_reclaim_params); + static __always_inline unsigned long __get_pfnblock_flags_mask(const struct page *page, unsigned long pfn, @@ -2919,10 +2943,14 @@ static void reserve_highatomic_pageblock(struct page *page, struct zone *zone, unsigned long max_managed, flags; /* - * Limit the number reserved to 1 pageblock or roughly 1% of a zone. + * The number reserved as: minimum is 1 pageblock, maximum is + * roughly 1% of a zone. But if 1% of a zone falls below a + * pageblock size, then don't reserve any pageblocks. * Check is race-prone but harmless. */ - max_managed = (zone_managed_pages(zone) / 100) + pageblock_nr_pages; + if ((zone_managed_pages(zone) / 100) < pageblock_nr_pages) + return; + max_managed = ALIGN((zone_managed_pages(zone) / 100), pageblock_nr_pages); if (zone->nr_reserved_highatomic >= max_managed) return; @@ -5044,14 +5072,9 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order, else (*no_progress_loops)++; - /* - * Make sure we converge to OOM if we cannot make any progress - * several times in the row. - */ - if (*no_progress_loops > MAX_RECLAIM_RETRIES) { - /* Before OOM, exhaust highatomic_reserve */ - return unreserve_highatomic_pageblock(ac, true); - } + if (*no_progress_loops > MAX_RECLAIM_RETRIES) + goto out; + /* * Keep reclaiming pages while there is a chance this will lead @@ -5094,6 +5117,11 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order, schedule_timeout_uninterruptible(1); else cond_resched(); +out: + /* Before OOM, exhaust highatomic_reserve */ + if (!ret) + return unreserve_highatomic_pageblock(ac, true); + return ret; } diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 631668f9cdfd..b458746e4d44 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -4704,6 +4704,9 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info, if ((flags & (NFT_SET_EVAL | NFT_SET_OBJECT)) == (NFT_SET_EVAL | NFT_SET_OBJECT)) return -EOPNOTSUPP; + if ((flags & (NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT | NFT_SET_EVAL)) == + (NFT_SET_ANONYMOUS | NFT_SET_TIMEOUT)) + return -EOPNOTSUPP; } desc.dtype = 0; @@ -5125,6 +5128,7 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, if (list_empty(&set->bindings) && nft_set_is_anonymous(set)) { list_del_rcu(&set->list); + set->dead = 1; if (event) nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_KERNEL); @@ -9876,10 +9880,11 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) struct nft_trans *trans, *next; LIST_HEAD(set_update_list); struct nft_trans_elem *te; + int err = 0; if (action == NFNL_ABORT_VALIDATE && nf_tables_validate(net) < 0) - return -EAGAIN; + err = -EAGAIN; list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list, list) { @@ -10050,12 +10055,7 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) nf_tables_abort_release(trans); } - if (action == NFNL_ABORT_AUTOLOAD) - nf_tables_module_autoload(net); - else - nf_tables_module_autoload_cleanup(net); - - return 0; + return err; } static int nf_tables_abort(struct net *net, struct sk_buff *skb, @@ -10069,6 +10069,16 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb, ret = __nf_tables_abort(net, action); nft_gc_seq_end(nft_net, gc_seq); + WARN_ON_ONCE(!list_empty(&nft_net->commit_list)); + + /* module autoload needs to happen after GC sequence update because it + * temporarily releases and grabs mutex again. + */ + if (action == NFNL_ABORT_AUTOLOAD) + nf_tables_module_autoload(net); + else + nf_tables_module_autoload_cleanup(net); + mutex_unlock(&nft_net->commit_mutex); return ret; @@ -10866,9 +10876,10 @@ static void __net_exit nf_tables_exit_net(struct net *net) gc_seq = nft_gc_seq_begin(nft_net); - if (!list_empty(&nft_net->commit_list) || - !list_empty(&nft_net->module_list)) - __nf_tables_abort(net, NFNL_ABORT_NONE); + WARN_ON_ONCE(!list_empty(&nft_net->commit_list)); + + if (!list_empty(&nft_net->module_list)) + nf_tables_module_autoload_cleanup(net); __nft_release_tables(net); diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c index 680fe557686e..274b6f7e6bb5 100644 --- a/net/netfilter/nft_chain_filter.c +++ b/net/netfilter/nft_chain_filter.c @@ -357,9 +357,10 @@ static int nf_tables_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct nft_base_chain *basechain; struct nftables_pernet *nft_net; - struct nft_table *table; struct nft_chain *chain, *nr; + struct nft_table *table; struct nft_ctx ctx = { .net = dev_net(dev), }; @@ -371,7 +372,8 @@ static int nf_tables_netdev_event(struct notifier_block *this, nft_net = nft_pernet(ctx.net); mutex_lock(&nft_net->commit_mutex); list_for_each_entry(table, &nft_net->tables, list) { - if (table->family != NFPROTO_NETDEV) + if (table->family != NFPROTO_NETDEV && + table->family != NFPROTO_INET) continue; ctx.family = table->family; @@ -380,6 +382,11 @@ static int nf_tables_netdev_event(struct notifier_block *this, if (!nft_is_base_chain(chain)) continue; + basechain = nft_base_chain(chain); + if (table->family == NFPROTO_INET && + basechain->ops.hooknum != NF_INET_INGRESS) + continue; + ctx.chain = chain; nft_netdev_event(event, dev, &ctx); } diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 4e1cc31729b8..050672ccfa7e 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -2234,8 +2234,6 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, if (m) { rcu_barrier(); - nft_set_pipapo_match_destroy(ctx, set, m); - #ifdef NFT_PIPAPO_ALIGN free_percpu(m->scratch_aligned); #endif @@ -2250,8 +2248,7 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, if (priv->clone) { m = priv->clone; - if (priv->dirty) - nft_set_pipapo_match_destroy(ctx, set, m); + nft_set_pipapo_match_destroy(ctx, set, m); #ifdef NFT_PIPAPO_ALIGN free_percpu(priv->clone->scratch_aligned); diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index fb6337adef53..6767e19be79b 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -223,10 +223,17 @@ static void tls_decrypt_done(crypto_completion_data_t *data, int err) kfree(aead_req); - spin_lock_bh(&ctx->decrypt_compl_lock); - if (!atomic_dec_return(&ctx->decrypt_pending)) + if (atomic_dec_and_test(&ctx->decrypt_pending)) complete(&ctx->async_wait.completion); - spin_unlock_bh(&ctx->decrypt_compl_lock); +} + +static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx) +{ + if (!atomic_dec_and_test(&ctx->decrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + atomic_inc(&ctx->decrypt_pending); + + return ctx->async_wait.err; } static int tls_do_decryption(struct sock *sk, @@ -252,6 +259,7 @@ static int tls_do_decryption(struct sock *sk, aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, tls_decrypt_done, aead_req); + DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->decrypt_pending) < 1); atomic_inc(&ctx->decrypt_pending); } else { aead_request_set_callback(aead_req, @@ -439,9 +447,7 @@ static void tls_encrypt_done(crypto_completion_data_t *data, int err) struct scatterlist *sge; struct sk_msg *msg_en; struct tls_rec *rec; - bool ready = false; struct sock *sk; - int pending; rec = container_of(aead_req, struct tls_rec, aead_req); msg_en = &rec->msg_encrypted; @@ -477,23 +483,25 @@ static void tls_encrypt_done(crypto_completion_data_t *data, int err) /* If received record is at head of tx_list, schedule tx */ first_rec = list_first_entry(&ctx->tx_list, struct tls_rec, list); - if (rec == first_rec) - ready = true; + if (rec == first_rec) { + /* Schedule the transmission */ + if (!test_and_set_bit(BIT_TX_SCHEDULED, + &ctx->tx_bitmask)) + schedule_delayed_work(&ctx->tx_work.work, 1); + } } - spin_lock_bh(&ctx->encrypt_compl_lock); - pending = atomic_dec_return(&ctx->encrypt_pending); - - if (!pending && ctx->async_notify) + if (atomic_dec_and_test(&ctx->encrypt_pending)) complete(&ctx->async_wait.completion); - spin_unlock_bh(&ctx->encrypt_compl_lock); +} - if (!ready) - return; +static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx) +{ + if (!atomic_dec_and_test(&ctx->encrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + atomic_inc(&ctx->encrypt_pending); - /* Schedule the transmission */ - if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) - schedule_delayed_work(&ctx->tx_work.work, 1); + return ctx->async_wait.err; } static int tls_do_encryption(struct sock *sk, @@ -542,6 +550,7 @@ static int tls_do_encryption(struct sock *sk, /* Add the record in tx_list */ list_add_tail((struct list_head *)&rec->list, &ctx->tx_list); + DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->encrypt_pending) < 1); atomic_inc(&ctx->encrypt_pending); rc = crypto_aead_encrypt(aead_req); @@ -953,7 +962,6 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) int num_zc = 0; int orig_size; int ret = 0; - int pending; if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_CMSG_COMPAT)) @@ -1122,24 +1130,12 @@ trim_sgl: if (!num_async) { goto send_end; } else if (num_zc) { + int err; + /* Wait for pending encryptions to get completed */ - spin_lock_bh(&ctx->encrypt_compl_lock); - ctx->async_notify = true; - - pending = atomic_read(&ctx->encrypt_pending); - spin_unlock_bh(&ctx->encrypt_compl_lock); - if (pending) - crypto_wait_req(-EINPROGRESS, &ctx->async_wait); - else - reinit_completion(&ctx->async_wait.completion); - - /* There can be no concurrent accesses, since we have no - * pending encrypt operations - */ - WRITE_ONCE(ctx->async_notify, false); - - if (ctx->async_wait.err) { - ret = ctx->async_wait.err; + err = tls_encrypt_async_wait(ctx); + if (err) { + ret = err; copied = 0; } } @@ -2117,16 +2113,10 @@ put_on_rx_list: recv_end: if (async) { - int ret, pending; + int ret; /* Wait for all previously submitted records to be decrypted */ - spin_lock_bh(&ctx->decrypt_compl_lock); - reinit_completion(&ctx->async_wait.completion); - pending = atomic_read(&ctx->decrypt_pending); - spin_unlock_bh(&ctx->decrypt_compl_lock); - ret = 0; - if (pending) - ret = crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + ret = tls_decrypt_async_wait(ctx); __skb_queue_purge(&ctx->async_hold); if (ret) { @@ -2345,16 +2335,9 @@ void tls_sw_release_resources_tx(struct sock *sk) struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec, *tmp; - int pending; /* Wait for any pending async encryptions to complete */ - spin_lock_bh(&ctx->encrypt_compl_lock); - ctx->async_notify = true; - pending = atomic_read(&ctx->encrypt_pending); - spin_unlock_bh(&ctx->encrypt_compl_lock); - - if (pending) - crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + tls_encrypt_async_wait(ctx); tls_tx_records(sk, -1); @@ -2507,6 +2490,48 @@ void tls_update_rx_zc_capable(struct tls_context *tls_ctx) tls_ctx->prot_info.version != TLS_1_3_VERSION; } +static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct sock *sk) +{ + struct tls_sw_context_tx *sw_ctx_tx; + + if (!ctx->priv_ctx_tx) { + sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); + if (!sw_ctx_tx) + return NULL; + } else { + sw_ctx_tx = ctx->priv_ctx_tx; + } + + crypto_init_wait(&sw_ctx_tx->async_wait); + atomic_set(&sw_ctx_tx->encrypt_pending, 1); + INIT_LIST_HEAD(&sw_ctx_tx->tx_list); + INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); + sw_ctx_tx->tx_work.sk = sk; + + return sw_ctx_tx; +} + +static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx) +{ + struct tls_sw_context_rx *sw_ctx_rx; + + if (!ctx->priv_ctx_rx) { + sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); + if (!sw_ctx_rx) + return NULL; + } else { + sw_ctx_rx = ctx->priv_ctx_rx; + } + + crypto_init_wait(&sw_ctx_rx->async_wait); + atomic_set(&sw_ctx_rx->decrypt_pending, 1); + init_waitqueue_head(&sw_ctx_rx->wq); + skb_queue_head_init(&sw_ctx_rx->rx_list); + skb_queue_head_init(&sw_ctx_rx->async_hold); + + return sw_ctx_rx; +} + int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) { struct tls_context *tls_ctx = tls_get_ctx(sk); @@ -2528,48 +2553,22 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) } if (tx) { - if (!ctx->priv_ctx_tx) { - sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); - if (!sw_ctx_tx) { - rc = -ENOMEM; - goto out; - } - ctx->priv_ctx_tx = sw_ctx_tx; - } else { - sw_ctx_tx = - (struct tls_sw_context_tx *)ctx->priv_ctx_tx; - } - } else { - if (!ctx->priv_ctx_rx) { - sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); - if (!sw_ctx_rx) { - rc = -ENOMEM; - goto out; - } - ctx->priv_ctx_rx = sw_ctx_rx; - } else { - sw_ctx_rx = - (struct tls_sw_context_rx *)ctx->priv_ctx_rx; - } - } + ctx->priv_ctx_tx = init_ctx_tx(ctx, sk); + if (!ctx->priv_ctx_tx) + return -ENOMEM; - if (tx) { - crypto_init_wait(&sw_ctx_tx->async_wait); - spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); + sw_ctx_tx = ctx->priv_ctx_tx; crypto_info = &ctx->crypto_send.info; cctx = &ctx->tx; aead = &sw_ctx_tx->aead_send; - INIT_LIST_HEAD(&sw_ctx_tx->tx_list); - INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); - sw_ctx_tx->tx_work.sk = sk; } else { - crypto_init_wait(&sw_ctx_rx->async_wait); - spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); - init_waitqueue_head(&sw_ctx_rx->wq); + ctx->priv_ctx_rx = init_ctx_rx(ctx); + if (!ctx->priv_ctx_rx) + return -ENOMEM; + + sw_ctx_rx = ctx->priv_ctx_rx; crypto_info = &ctx->crypto_recv.info; cctx = &ctx->rx; - skb_queue_head_init(&sw_ctx_rx->rx_list); - skb_queue_head_init(&sw_ctx_rx->async_hold); aead = &sw_ctx_rx->aead_recv; } diff --git a/sound/virtio/Makefile b/sound/virtio/Makefile index 2742bddb8874..a839f8c8b5e6 100644 --- a/sound/virtio/Makefile +++ b/sound/virtio/Makefile @@ -7,6 +7,7 @@ virtio_snd-objs := \ virtio_chmap.o \ virtio_ctl_msg.o \ virtio_jack.o \ + virtio_kctl.o \ virtio_pcm.o \ virtio_pcm_msg.o \ virtio_pcm_ops.o diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c index e2847c040f75..61df3476cf70 100644 --- a/sound/virtio/virtio_card.c +++ b/sound/virtio/virtio_card.c @@ -64,6 +64,9 @@ static void virtsnd_event_dispatch(struct virtio_snd *snd, case VIRTIO_SND_EVT_PCM_XRUN: virtsnd_pcm_event(snd, event); break; + case VIRTIO_SND_EVT_CTL_NOTIFY: + virtsnd_kctl_event(snd, event); + break; } } @@ -235,6 +238,12 @@ static int virtsnd_build_devs(struct virtio_snd *snd) if (rc) return rc; + if (virtio_has_feature(vdev, VIRTIO_SND_F_CTLS)) { + rc = virtsnd_kctl_parse_cfg(snd); + if (rc) + return rc; + } + if (snd->njacks) { rc = virtsnd_jack_build_devs(snd); if (rc) @@ -253,6 +262,12 @@ static int virtsnd_build_devs(struct virtio_snd *snd) return rc; } + if (snd->nkctls) { + rc = virtsnd_kctl_build_devs(snd); + if (rc) + return rc; + } + return snd_card_register(snd->card); } @@ -419,10 +434,16 @@ static const struct virtio_device_id id_table[] = { { 0 }, }; +static unsigned int features[] = { + VIRTIO_SND_F_CTLS +}; + static struct virtio_driver virtsnd_driver = { .driver.name = KBUILD_MODNAME, .driver.owner = THIS_MODULE, .id_table = id_table, + .feature_table = features, + .feature_table_size = ARRAY_SIZE(features), .validate = virtsnd_validate, .probe = virtsnd_probe, .remove = virtsnd_remove, diff --git a/sound/virtio/virtio_card.h b/sound/virtio/virtio_card.h index 86ef3941895e..3ceee4e416fc 100644 --- a/sound/virtio/virtio_card.h +++ b/sound/virtio/virtio_card.h @@ -31,6 +31,16 @@ struct virtio_snd_queue { struct virtqueue *vqueue; }; +/** + * struct virtio_kctl - VirtIO control element. + * @kctl: ALSA control element. + * @items: Items for the ENUMERATED element type. + */ +struct virtio_kctl { + struct snd_kcontrol *kctl; + struct virtio_snd_ctl_enum_item *items; +}; + /** * struct virtio_snd - VirtIO sound card device. * @vdev: Underlying virtio device. @@ -45,6 +55,9 @@ struct virtio_snd_queue { * @nsubstreams: Number of PCM substreams. * @chmaps: VirtIO channel maps. * @nchmaps: Number of channel maps. + * @kctl_infos: VirtIO control element information. + * @kctls: VirtIO control elements. + * @nkctls: Number of control elements. */ struct virtio_snd { struct virtio_device *vdev; @@ -59,6 +72,9 @@ struct virtio_snd { u32 nsubstreams; struct virtio_snd_chmap_info *chmaps; u32 nchmaps; + struct virtio_snd_ctl_info *kctl_infos; + struct virtio_kctl *kctls; + u32 nkctls; }; /* Message completion timeout in milliseconds (module parameter). */ @@ -108,4 +124,10 @@ int virtsnd_chmap_parse_cfg(struct virtio_snd *snd); int virtsnd_chmap_build_devs(struct virtio_snd *snd); +int virtsnd_kctl_parse_cfg(struct virtio_snd *snd); + +int virtsnd_kctl_build_devs(struct virtio_snd *snd); + +void virtsnd_kctl_event(struct virtio_snd *snd, struct virtio_snd_event *event); + #endif /* VIRTIO_SND_CARD_H */ diff --git a/sound/virtio/virtio_kctl.c b/sound/virtio/virtio_kctl.c new file mode 100644 index 000000000000..7aa79c05b464 --- /dev/null +++ b/sound/virtio/virtio_kctl.c @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * virtio-snd: Virtio sound device + * Copyright (C) 2022 OpenSynergy GmbH + */ +#include +#include + +#include "virtio_card.h" + +/* Map for converting VirtIO types to ALSA types. */ +static const snd_ctl_elem_type_t g_v2a_type_map[] = { + [VIRTIO_SND_CTL_TYPE_BOOLEAN] = SNDRV_CTL_ELEM_TYPE_BOOLEAN, + [VIRTIO_SND_CTL_TYPE_INTEGER] = SNDRV_CTL_ELEM_TYPE_INTEGER, + [VIRTIO_SND_CTL_TYPE_INTEGER64] = SNDRV_CTL_ELEM_TYPE_INTEGER64, + [VIRTIO_SND_CTL_TYPE_ENUMERATED] = SNDRV_CTL_ELEM_TYPE_ENUMERATED, + [VIRTIO_SND_CTL_TYPE_BYTES] = SNDRV_CTL_ELEM_TYPE_BYTES, + [VIRTIO_SND_CTL_TYPE_IEC958] = SNDRV_CTL_ELEM_TYPE_IEC958 +}; + +/* Map for converting VirtIO access rights to ALSA access rights. */ +static const unsigned int g_v2a_access_map[] = { + [VIRTIO_SND_CTL_ACCESS_READ] = SNDRV_CTL_ELEM_ACCESS_READ, + [VIRTIO_SND_CTL_ACCESS_WRITE] = SNDRV_CTL_ELEM_ACCESS_WRITE, + [VIRTIO_SND_CTL_ACCESS_VOLATILE] = SNDRV_CTL_ELEM_ACCESS_VOLATILE, + [VIRTIO_SND_CTL_ACCESS_INACTIVE] = SNDRV_CTL_ELEM_ACCESS_INACTIVE, + [VIRTIO_SND_CTL_ACCESS_TLV_READ] = SNDRV_CTL_ELEM_ACCESS_TLV_READ, + [VIRTIO_SND_CTL_ACCESS_TLV_WRITE] = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE, + [VIRTIO_SND_CTL_ACCESS_TLV_COMMAND] = SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND +}; + +/* Map for converting VirtIO event masks to ALSA event masks. */ +static const unsigned int g_v2a_mask_map[] = { + [VIRTIO_SND_CTL_EVT_MASK_VALUE] = SNDRV_CTL_EVENT_MASK_VALUE, + [VIRTIO_SND_CTL_EVT_MASK_INFO] = SNDRV_CTL_EVENT_MASK_INFO, + [VIRTIO_SND_CTL_EVT_MASK_TLV] = SNDRV_CTL_EVENT_MASK_TLV +}; + +/** + * virtsnd_kctl_info() - Returns information about the control. + * @kcontrol: ALSA control element. + * @uinfo: Element information. + * + * Context: Process context. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_kctl_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct virtio_snd *snd = kcontrol->private_data; + struct virtio_kctl *kctl = &snd->kctls[kcontrol->private_value]; + struct virtio_snd_ctl_info *kinfo = + &snd->kctl_infos[kcontrol->private_value]; + unsigned int i; + + uinfo->type = g_v2a_type_map[le32_to_cpu(kinfo->type)]; + uinfo->count = le32_to_cpu(kinfo->count); + + switch (uinfo->type) { + case SNDRV_CTL_ELEM_TYPE_INTEGER: + uinfo->value.integer.min = + le32_to_cpu(kinfo->value.integer.min); + uinfo->value.integer.max = + le32_to_cpu(kinfo->value.integer.max); + uinfo->value.integer.step = + le32_to_cpu(kinfo->value.integer.step); + + break; + case SNDRV_CTL_ELEM_TYPE_INTEGER64: + uinfo->value.integer64.min = + le64_to_cpu(kinfo->value.integer64.min); + uinfo->value.integer64.max = + le64_to_cpu(kinfo->value.integer64.max); + uinfo->value.integer64.step = + le64_to_cpu(kinfo->value.integer64.step); + + break; + case SNDRV_CTL_ELEM_TYPE_ENUMERATED: + uinfo->value.enumerated.items = + le32_to_cpu(kinfo->value.enumerated.items); + i = uinfo->value.enumerated.item; + if (i >= uinfo->value.enumerated.items) + return -EINVAL; + + strscpy(uinfo->value.enumerated.name, kctl->items[i].item, + sizeof(uinfo->value.enumerated.name)); + + break; + } + + return 0; +} + +/** + * virtsnd_kctl_get() - Read the value from the control. + * @kcontrol: ALSA control element. + * @uvalue: Element value. + * + * Context: Process context. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_kctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct virtio_snd *snd = kcontrol->private_data; + struct virtio_snd_ctl_info *kinfo = + &snd->kctl_infos[kcontrol->private_value]; + unsigned int type = le32_to_cpu(kinfo->type); + unsigned int count = le32_to_cpu(kinfo->count); + struct virtio_snd_msg *msg; + struct virtio_snd_ctl_hdr *hdr; + struct virtio_snd_ctl_value *kvalue; + size_t request_size = sizeof(*hdr); + size_t response_size = sizeof(struct virtio_snd_hdr) + sizeof(*kvalue); + unsigned int i; + int rc; + + msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + virtsnd_ctl_msg_ref(msg); + + hdr = virtsnd_ctl_msg_request(msg); + hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_READ); + hdr->control_id = cpu_to_le32(kcontrol->private_value); + + rc = virtsnd_ctl_msg_send_sync(snd, msg); + if (rc) + goto on_failure; + + kvalue = (void *)((u8 *)virtsnd_ctl_msg_response(msg) + + sizeof(struct virtio_snd_hdr)); + + switch (type) { + case VIRTIO_SND_CTL_TYPE_BOOLEAN: + case VIRTIO_SND_CTL_TYPE_INTEGER: + for (i = 0; i < count; ++i) + uvalue->value.integer.value[i] = + le32_to_cpu(kvalue->value.integer[i]); + break; + case VIRTIO_SND_CTL_TYPE_INTEGER64: + for (i = 0; i < count; ++i) + uvalue->value.integer64.value[i] = + le64_to_cpu(kvalue->value.integer64[i]); + break; + case VIRTIO_SND_CTL_TYPE_ENUMERATED: + for (i = 0; i < count; ++i) + uvalue->value.enumerated.item[i] = + le32_to_cpu(kvalue->value.enumerated[i]); + break; + case VIRTIO_SND_CTL_TYPE_BYTES: + memcpy(uvalue->value.bytes.data, kvalue->value.bytes, count); + break; + case VIRTIO_SND_CTL_TYPE_IEC958: + memcpy(&uvalue->value.iec958, &kvalue->value.iec958, + sizeof(uvalue->value.iec958)); + break; + } + +on_failure: + virtsnd_ctl_msg_unref(msg); + + return rc; +} + +/** + * virtsnd_kctl_put() - Write the value to the control. + * @kcontrol: ALSA control element. + * @uvalue: Element value. + * + * Context: Process context. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_kctl_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + struct virtio_snd *snd = kcontrol->private_data; + struct virtio_snd_ctl_info *kinfo = + &snd->kctl_infos[kcontrol->private_value]; + unsigned int type = le32_to_cpu(kinfo->type); + unsigned int count = le32_to_cpu(kinfo->count); + struct virtio_snd_msg *msg; + struct virtio_snd_ctl_hdr *hdr; + struct virtio_snd_ctl_value *kvalue; + size_t request_size = sizeof(*hdr) + sizeof(*kvalue); + size_t response_size = sizeof(struct virtio_snd_hdr); + unsigned int i; + + msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + hdr = virtsnd_ctl_msg_request(msg); + hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_WRITE); + hdr->control_id = cpu_to_le32(kcontrol->private_value); + + kvalue = (void *)((u8 *)hdr + sizeof(*hdr)); + + switch (type) { + case VIRTIO_SND_CTL_TYPE_BOOLEAN: + case VIRTIO_SND_CTL_TYPE_INTEGER: + for (i = 0; i < count; ++i) + kvalue->value.integer[i] = + cpu_to_le32(uvalue->value.integer.value[i]); + break; + case VIRTIO_SND_CTL_TYPE_INTEGER64: + for (i = 0; i < count; ++i) + kvalue->value.integer64[i] = + cpu_to_le64(uvalue->value.integer64.value[i]); + break; + case VIRTIO_SND_CTL_TYPE_ENUMERATED: + for (i = 0; i < count; ++i) + kvalue->value.enumerated[i] = + cpu_to_le32(uvalue->value.enumerated.item[i]); + break; + case VIRTIO_SND_CTL_TYPE_BYTES: + memcpy(kvalue->value.bytes, uvalue->value.bytes.data, count); + break; + case VIRTIO_SND_CTL_TYPE_IEC958: + memcpy(&kvalue->value.iec958, &uvalue->value.iec958, + sizeof(kvalue->value.iec958)); + break; + } + + return virtsnd_ctl_msg_send_sync(snd, msg); +} + +/** + * virtsnd_kctl_tlv_op() - Perform an operation on the control's metadata. + * @kcontrol: ALSA control element. + * @op_flag: Operation code (SNDRV_CTL_TLV_OP_XXX). + * @size: Size of the TLV data in bytes. + * @utlv: TLV data. + * + * Context: Process context. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_kctl_tlv_op(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *utlv) +{ + struct virtio_snd *snd = kcontrol->private_data; + struct virtio_snd_msg *msg; + struct virtio_snd_ctl_hdr *hdr; + unsigned int *tlv; + struct scatterlist sg; + int rc; + + msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), sizeof(struct virtio_snd_hdr), + GFP_KERNEL); + if (!msg) + return -ENOMEM; + + tlv = kzalloc(size, GFP_KERNEL); + if (!tlv) { + rc = -ENOMEM; + goto on_msg_unref; + } + + sg_init_one(&sg, tlv, size); + + hdr = virtsnd_ctl_msg_request(msg); + hdr->control_id = cpu_to_le32(kcontrol->private_value); + + switch (op_flag) { + case SNDRV_CTL_TLV_OP_READ: + hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_READ); + + rc = virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); + if (!rc) { + if (copy_to_user(utlv, tlv, size)) + rc = -EFAULT; + } + + break; + case SNDRV_CTL_TLV_OP_WRITE: + case SNDRV_CTL_TLV_OP_CMD: + if (op_flag == SNDRV_CTL_TLV_OP_WRITE) + hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_WRITE); + else + hdr->hdr.code = + cpu_to_le32(VIRTIO_SND_R_CTL_TLV_COMMAND); + + if (copy_from_user(tlv, utlv, size)) { + rc = -EFAULT; + goto on_msg_unref; + } else { + rc = virtsnd_ctl_msg_send(snd, msg, &sg, NULL, false); + } + + break; + default: + rc = -EINVAL; + /* We never get here - we listed all values for op_flag */ + WARN_ON(1); + goto on_msg_unref; + } + kfree(tlv); + return rc; + +on_msg_unref: + virtsnd_ctl_msg_unref(msg); + kfree(tlv); + + return rc; +} + +/** + * virtsnd_kctl_get_enum_items() - Query items for the ENUMERATED element type. + * @snd: VirtIO sound device. + * @cid: Control element ID. + * + * This function is called during initial device initialization. + * + * Context: Any context that permits to sleep. + * Return: 0 on success, -errno on failure. + */ +static int virtsnd_kctl_get_enum_items(struct virtio_snd *snd, unsigned int cid) +{ + struct virtio_device *vdev = snd->vdev; + struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; + struct virtio_kctl *kctl = &snd->kctls[cid]; + struct virtio_snd_msg *msg; + struct virtio_snd_ctl_hdr *hdr; + unsigned int n = le32_to_cpu(kinfo->value.enumerated.items); + struct scatterlist sg; + + msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), + sizeof(struct virtio_snd_hdr), GFP_KERNEL); + if (!msg) + return -ENOMEM; + + kctl->items = devm_kcalloc(&vdev->dev, n, sizeof(*kctl->items), + GFP_KERNEL); + if (!kctl->items) { + virtsnd_ctl_msg_unref(msg); + return -ENOMEM; + } + + sg_init_one(&sg, kctl->items, n * sizeof(*kctl->items)); + + hdr = virtsnd_ctl_msg_request(msg); + hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_ENUM_ITEMS); + hdr->control_id = cpu_to_le32(cid); + + return virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); +} + +/** + * virtsnd_kctl_parse_cfg() - Parse the control element configuration. + * @snd: VirtIO sound device. + * + * This function is called during initial device initialization. + * + * Context: Any context that permits to sleep. + * Return: 0 on success, -errno on failure. + */ +int virtsnd_kctl_parse_cfg(struct virtio_snd *snd) +{ + struct virtio_device *vdev = snd->vdev; + u32 i; + int rc; + + virtio_cread_le(vdev, struct virtio_snd_config, controls, + &snd->nkctls); + if (!snd->nkctls) + return 0; + + snd->kctl_infos = devm_kcalloc(&vdev->dev, snd->nkctls, + sizeof(*snd->kctl_infos), GFP_KERNEL); + if (!snd->kctl_infos) + return -ENOMEM; + + snd->kctls = devm_kcalloc(&vdev->dev, snd->nkctls, sizeof(*snd->kctls), + GFP_KERNEL); + if (!snd->kctls) + return -ENOMEM; + + rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_CTL_INFO, 0, snd->nkctls, + sizeof(*snd->kctl_infos), snd->kctl_infos); + if (rc) + return rc; + + for (i = 0; i < snd->nkctls; ++i) { + struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i]; + unsigned int type = le32_to_cpu(kinfo->type); + + if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED) { + rc = virtsnd_kctl_get_enum_items(snd, i); + if (rc) + return rc; + } + } + + return 0; +} + +/** + * virtsnd_kctl_build_devs() - Build ALSA control elements. + * @snd: VirtIO sound device. + * + * Context: Any context that permits to sleep. + * Return: 0 on success, -errno on failure. + */ +int virtsnd_kctl_build_devs(struct virtio_snd *snd) +{ + unsigned int cid; + + for (cid = 0; cid < snd->nkctls; ++cid) { + struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; + struct virtio_kctl *kctl = &snd->kctls[cid]; + struct snd_kcontrol_new kctl_new; + unsigned int i; + int rc; + + memset(&kctl_new, 0, sizeof(kctl_new)); + + kctl_new.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + kctl_new.name = kinfo->name; + kctl_new.index = le32_to_cpu(kinfo->index); + + for (i = 0; i < ARRAY_SIZE(g_v2a_access_map); ++i) + if (le32_to_cpu(kinfo->access) & (1 << i)) + kctl_new.access |= g_v2a_access_map[i]; + + if (kctl_new.access & (SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_WRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND)) { + kctl_new.access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + kctl_new.tlv.c = virtsnd_kctl_tlv_op; + } + + kctl_new.info = virtsnd_kctl_info; + kctl_new.get = virtsnd_kctl_get; + kctl_new.put = virtsnd_kctl_put; + kctl_new.private_value = cid; + + kctl->kctl = snd_ctl_new1(&kctl_new, snd); + if (!kctl->kctl) + return -ENOMEM; + + rc = snd_ctl_add(snd->card, kctl->kctl); + if (rc) + return rc; + } + + return 0; +} + +/** + * virtsnd_kctl_event() - Handle the control element event notification. + * @snd: VirtIO sound device. + * @event: VirtIO sound event. + * + * Context: Interrupt context. + */ +void virtsnd_kctl_event(struct virtio_snd *snd, struct virtio_snd_event *event) +{ + struct virtio_snd_ctl_event *kevent = + (struct virtio_snd_ctl_event *)event; + struct virtio_kctl *kctl; + unsigned int cid = le16_to_cpu(kevent->control_id); + unsigned int mask = 0; + unsigned int i; + + if (cid >= snd->nkctls) + return; + + for (i = 0; i < ARRAY_SIZE(g_v2a_mask_map); ++i) + if (le16_to_cpu(kevent->mask) & (1 << i)) + mask |= g_v2a_mask_map[i]; + + + kctl = &snd->kctls[cid]; + + snd_ctl_notify(snd->card, mask, &kctl->kctl->id); +}