LTS: Merge android-4.19-stable (4.19.269) into android-msm-pixel-4.19
Merge android-4.19-stable common kernel (4.19.269) into B5R3/B9 Mainline kernel.
Bug: 263916797
Test: Manual testing, SST, vts/vts-kernel, pts/base, pts/postsubmit-long
Signed-off-by: Wilson Sung <wilsonsung@google.com>
Change-Id: I1dd57d90f7683bad4fcf71d004b8b3b53c80b9f6
Signed-off-by: JohnnLee <johnnlee@google.com>
diff --git a/android/abi_gki_aarch64_redbull b/android/abi_gki_aarch64_redbull
index bea8c5c..109a1fa 100644
--- a/android/abi_gki_aarch64_redbull
+++ b/android/abi_gki_aarch64_redbull
@@ -493,7 +493,6 @@
media_device_unregister
media_entity_pads_init
memchr
- memchr_inv
memcmp
memcpy
__memcpy_fromio
@@ -1439,6 +1438,7 @@
match_int
match_strdup
match_token
+ memchr_inv
noop_llseek
notify_change
override_creds
@@ -1581,6 +1581,7 @@
# required by msm_adreno.ko
bpf_trace_run10
+ check_zeroed_user
__clk_get_name
devfreq_cooling_unregister
device_show_int
diff --git a/android/abi_gki_aarch64_redbull.xml b/android/abi_gki_aarch64_redbull.xml
index cfa1a27..0a36d5d 100644
--- a/android/abi_gki_aarch64_redbull.xml
+++ b/android/abi_gki_aarch64_redbull.xml
@@ -321,6 +321,7 @@
<elf-symbol name='cfg80211_unlink_bss' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xac7f9cb'/>
<elf-symbol name='cfg80211_update_owe_info_event' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x47378385'/>
<elf-symbol name='cfg80211_vendor_cmd_reply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0xc0c343b4'/>
+ <elf-symbol name='check_zeroed_user' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2db3bc61'/>
<elf-symbol name='class_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x483be9d'/>
<elf-symbol name='class_find_device' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x655c072a'/>
<elf-symbol name='clear_inode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes' crc='0x2483b2a1'/>
@@ -3584,7 +3585,7 @@
<pointer-type-def type-id='5ea5a07d' size-in-bits='64' id='f69fcfe1'/>
<pointer-type-def type-id='449f791f' size-in-bits='64' id='cc3e2efb'/>
<typedef-decl name='wait_queue_head_t' type-id='cff07063' filepath='include/linux/wait.h' line='39' column='1' id='b5ab048f'/>
- <union-decl name='__anonymous_union__3' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/trace_events.h' line='256' column='1' id='7d3eb798'>
+ <union-decl name='__anonymous_union__4' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='include/linux/trace_events.h' line='256' column='1' id='7d3eb798'>
<data-member access='public'>
<var-decl name='name' type-id='26a90f95' visibility='default' filepath='include/linux/trace_events.h' line='257' column='1'/>
</data-member>
@@ -57332,9 +57333,9 @@
</function-type>
</abi-instr>
<abi-instr address-size='64' path='drivers/dma-buf/dma-buf.c' language='LANG_C89'>
- <function-decl name='dma_buf_begin_cpu_access' mangled-name='dma_buf_begin_cpu_access' filepath='drivers/dma-buf/dma-buf.c' line='1012' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_begin_cpu_access'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1012' column='1'/>
- <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1013' column='1'/>
+ <function-decl name='dma_buf_begin_cpu_access' mangled-name='dma_buf_begin_cpu_access' filepath='drivers/dma-buf/dma-buf.c' line='1025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_begin_cpu_access'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1025' column='1'/>
+ <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1026' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='reservation_object_wait_timeout_rcu' mangled-name='reservation_object_wait_timeout_rcu' filepath='include/linux/reservation.h' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reservation_object_wait_timeout_rcu'>
@@ -57344,48 +57345,48 @@
<parameter type-id='7359adad'/>
<return type-id='bd54fe1a'/>
</function-decl>
- <function-decl name='dma_buf_begin_cpu_access_partial' mangled-name='dma_buf_begin_cpu_access_partial' filepath='drivers/dma-buf/dma-buf.c' line='1055' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_begin_cpu_access_partial'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1055' column='1'/>
- <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1056' column='1'/>
- <parameter type-id='f0981eeb' name='offset' filepath='drivers/dma-buf/dma-buf.c' line='1057' column='1'/>
- <parameter type-id='f0981eeb' name='len' filepath='drivers/dma-buf/dma-buf.c' line='1057' column='1'/>
+ <function-decl name='dma_buf_begin_cpu_access_partial' mangled-name='dma_buf_begin_cpu_access_partial' filepath='drivers/dma-buf/dma-buf.c' line='1068' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_begin_cpu_access_partial'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1068' column='1'/>
+ <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1069' column='1'/>
+ <parameter type-id='f0981eeb' name='offset' filepath='drivers/dma-buf/dma-buf.c' line='1070' column='1'/>
+ <parameter type-id='f0981eeb' name='len' filepath='drivers/dma-buf/dma-buf.c' line='1070' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='dma_buf_end_cpu_access' mangled-name='dma_buf_end_cpu_access' filepath='drivers/dma-buf/dma-buf.c' line='1091' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_end_cpu_access'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1091' column='1'/>
- <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1092' column='1'/>
+ <function-decl name='dma_buf_end_cpu_access' mangled-name='dma_buf_end_cpu_access' filepath='drivers/dma-buf/dma-buf.c' line='1104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_end_cpu_access'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1104' column='1'/>
+ <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1105' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='dma_buf_end_cpu_access_partial' mangled-name='dma_buf_end_cpu_access_partial' filepath='drivers/dma-buf/dma-buf.c' line='1118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_end_cpu_access_partial'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1118' column='1'/>
- <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1119' column='1'/>
- <parameter type-id='f0981eeb' name='offset' filepath='drivers/dma-buf/dma-buf.c' line='1120' column='1'/>
- <parameter type-id='f0981eeb' name='len' filepath='drivers/dma-buf/dma-buf.c' line='1120' column='1'/>
+ <function-decl name='dma_buf_end_cpu_access_partial' mangled-name='dma_buf_end_cpu_access_partial' filepath='drivers/dma-buf/dma-buf.c' line='1131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_end_cpu_access_partial'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1131' column='1'/>
+ <parameter type-id='eea6b025' name='direction' filepath='drivers/dma-buf/dma-buf.c' line='1132' column='1'/>
+ <parameter type-id='f0981eeb' name='offset' filepath='drivers/dma-buf/dma-buf.c' line='1133' column='1'/>
+ <parameter type-id='f0981eeb' name='len' filepath='drivers/dma-buf/dma-buf.c' line='1133' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='dma_buf_kmap' mangled-name='dma_buf_kmap' filepath='drivers/dma-buf/dma-buf.c' line='1143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_kmap'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1143' column='1'/>
- <parameter type-id='7359adad' name='page_num' filepath='drivers/dma-buf/dma-buf.c' line='1143' column='1'/>
+ <function-decl name='dma_buf_kmap' mangled-name='dma_buf_kmap' filepath='drivers/dma-buf/dma-buf.c' line='1156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_kmap'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1156' column='1'/>
+ <parameter type-id='7359adad' name='page_num' filepath='drivers/dma-buf/dma-buf.c' line='1156' column='1'/>
<return type-id='eaa32e2f'/>
</function-decl>
- <function-decl name='dma_buf_kunmap' mangled-name='dma_buf_kunmap' filepath='drivers/dma-buf/dma-buf.c' line='1161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_kunmap'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1161' column='1'/>
- <parameter type-id='7359adad' name='page_num' filepath='drivers/dma-buf/dma-buf.c' line='1161' column='1'/>
- <parameter type-id='eaa32e2f' name='vaddr' filepath='drivers/dma-buf/dma-buf.c' line='1162' column='1'/>
+ <function-decl name='dma_buf_kunmap' mangled-name='dma_buf_kunmap' filepath='drivers/dma-buf/dma-buf.c' line='1174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_kunmap'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1174' column='1'/>
+ <parameter type-id='7359adad' name='page_num' filepath='drivers/dma-buf/dma-buf.c' line='1174' column='1'/>
+ <parameter type-id='eaa32e2f' name='vaddr' filepath='drivers/dma-buf/dma-buf.c' line='1175' column='1'/>
<return type-id='48b5725f'/>
</function-decl>
- <function-decl name='dma_buf_vmap' mangled-name='dma_buf_vmap' filepath='drivers/dma-buf/dma-buf.c' line='1236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_vmap'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1236' column='1'/>
+ <function-decl name='dma_buf_vmap' mangled-name='dma_buf_vmap' filepath='drivers/dma-buf/dma-buf.c' line='1249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_vmap'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1249' column='1'/>
<return type-id='eaa32e2f'/>
</function-decl>
- <function-decl name='dma_buf_vunmap' mangled-name='dma_buf_vunmap' filepath='drivers/dma-buf/dma-buf.c' line='1276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_vunmap'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1276' column='1'/>
- <parameter type-id='eaa32e2f' name='vaddr' filepath='drivers/dma-buf/dma-buf.c' line='1276' column='1'/>
+ <function-decl name='dma_buf_vunmap' mangled-name='dma_buf_vunmap' filepath='drivers/dma-buf/dma-buf.c' line='1289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_vunmap'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1289' column='1'/>
+ <parameter type-id='eaa32e2f' name='vaddr' filepath='drivers/dma-buf/dma-buf.c' line='1289' column='1'/>
<return type-id='48b5725f'/>
</function-decl>
- <function-decl name='dma_buf_get_flags' mangled-name='dma_buf_get_flags' filepath='drivers/dma-buf/dma-buf.c' line='1295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_get_flags'>
- <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1295' column='1'/>
- <parameter type-id='1d2c2b85' name='flags' filepath='drivers/dma-buf/dma-buf.c' line='1295' column='1'/>
+ <function-decl name='dma_buf_get_flags' mangled-name='dma_buf_get_flags' filepath='drivers/dma-buf/dma-buf.c' line='1308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='dma_buf_get_flags'>
+ <parameter type-id='5e4f599b' name='dmabuf' filepath='drivers/dma-buf/dma-buf.c' line='1308' column='1'/>
+ <parameter type-id='1d2c2b85' name='flags' filepath='drivers/dma-buf/dma-buf.c' line='1308' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
<pointer-type-def type-id='c201baab' size-in-bits='64' id='5e4f599b'/>
@@ -92841,25 +92842,25 @@
</function-type>
</abi-instr>
<abi-instr address-size='64' path='drivers/nvmem/core.c' language='LANG_C89'>
- <function-decl name='devm_nvmem_register' mangled-name='devm_nvmem_register' filepath='drivers/nvmem/core.c' line='476' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_register'>
- <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='476' column='1'/>
- <parameter type-id='7bb280fa' name='config' filepath='drivers/nvmem/core.c' line='477' column='1'/>
+ <function-decl name='devm_nvmem_register' mangled-name='devm_nvmem_register' filepath='drivers/nvmem/core.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_register'>
+ <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='477' column='1'/>
+ <parameter type-id='7bb280fa' name='config' filepath='drivers/nvmem/core.c' line='478' column='1'/>
<return type-id='8179bc49'/>
</function-decl>
- <function-decl name='devm_nvmem_device_get' mangled-name='devm_nvmem_device_get' filepath='drivers/nvmem/core.c' line='673' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_device_get'>
- <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='673' column='1'/>
- <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='673' column='1'/>
+ <function-decl name='devm_nvmem_device_get' mangled-name='devm_nvmem_device_get' filepath='drivers/nvmem/core.c' line='674' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='devm_nvmem_device_get'>
+ <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='674' column='1'/>
+ <parameter type-id='80f4b756' name='id' filepath='drivers/nvmem/core.c' line='674' column='1'/>
<return type-id='8179bc49'/>
</function-decl>
- <function-decl name='nvmem_cell_get' mangled-name='nvmem_cell_get' filepath='drivers/nvmem/core.c' line='779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_get'>
- <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='779' column='1'/>
- <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='779' column='1'/>
+ <function-decl name='nvmem_cell_get' mangled-name='nvmem_cell_get' filepath='drivers/nvmem/core.c' line='780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_get'>
+ <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='780' column='1'/>
+ <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='780' column='1'/>
<return type-id='4a4ce85f'/>
</function-decl>
- <function-decl name='nvmem_cell_read_u32' mangled-name='nvmem_cell_read_u32' filepath='drivers/nvmem/core.c' line='1059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read_u32'>
- <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1059' column='1'/>
- <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='1059' column='1'/>
- <parameter type-id='f9409001' name='val' filepath='drivers/nvmem/core.c' line='1059' column='1'/>
+ <function-decl name='nvmem_cell_read_u32' mangled-name='nvmem_cell_read_u32' filepath='drivers/nvmem/core.c' line='1060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='nvmem_cell_read_u32'>
+ <parameter type-id='fa0b179b' name='dev' filepath='drivers/nvmem/core.c' line='1060' column='1'/>
+ <parameter type-id='80f4b756' name='cell_id' filepath='drivers/nvmem/core.c' line='1060' column='1'/>
+ <parameter type-id='f9409001' name='val' filepath='drivers/nvmem/core.c' line='1060' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
<pointer-type-def type-id='a9ae7f74' size-in-bits='64' id='7bb280fa'/>
@@ -103867,8 +103868,8 @@
<parameter type-id='1a494567'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='usb_composite_setup_continue' mangled-name='usb_composite_setup_continue' filepath='drivers/usb/gadget/composite.c' line='2660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_setup_continue'>
- <parameter type-id='2a895c01' name='cdev' filepath='drivers/usb/gadget/composite.c' line='2660' column='1'/>
+ <function-decl name='usb_composite_setup_continue' mangled-name='usb_composite_setup_continue' filepath='drivers/usb/gadget/composite.c' line='2659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='usb_composite_setup_continue'>
+ <parameter type-id='2a895c01' name='cdev' filepath='drivers/usb/gadget/composite.c' line='2659' column='1'/>
<return type-id='48b5725f'/>
</function-decl>
<pointer-type-def type-id='e9546509' size-in-bits='64' id='2a895c01'/>
@@ -114022,7 +114023,7 @@
<parameter type-id='7292109c'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='find_last_bit' mangled-name='find_last_bit' filepath='include/linux/bitops.h' line='277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_last_bit'>
+ <function-decl name='find_last_bit' mangled-name='find_last_bit' filepath='include/linux/bitops.h' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='find_last_bit'>
<parameter type-id='f9b37274'/>
<parameter type-id='7359adad'/>
<return type-id='7359adad'/>
@@ -116873,20 +116874,20 @@
<parameter type-id='538ece95'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='sched_setscheduler' mangled-name='sched_setscheduler' filepath='kernel/sched/core.c' line='5225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler'>
- <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5225' column='1'/>
- <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5225' column='1'/>
- <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5226' column='1'/>
+ <function-decl name='sched_setscheduler' mangled-name='sched_setscheduler' filepath='kernel/sched/core.c' line='5233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setscheduler'>
+ <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5233' column='1'/>
+ <parameter type-id='95e97e5e' name='policy' filepath='kernel/sched/core.c' line='5233' column='1'/>
+ <parameter type-id='36fca399' name='param' filepath='kernel/sched/core.c' line='5234' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='sched_setattr' mangled-name='sched_setattr' filepath='kernel/sched/core.c' line='5232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr'>
- <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5232' column='1'/>
- <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5232' column='1'/>
+ <function-decl name='sched_setattr' mangled-name='sched_setattr' filepath='kernel/sched/core.c' line='5240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setattr'>
+ <parameter type-id='f23e2572' name='p' filepath='kernel/sched/core.c' line='5240' column='1'/>
+ <parameter type-id='8abbb6c3' name='attr' filepath='kernel/sched/core.c' line='5240' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='sched_setaffinity' mangled-name='sched_setaffinity' filepath='kernel/sched/core.c' line='5589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setaffinity'>
- <parameter type-id='587f89d2' name='pid' filepath='kernel/sched/core.c' line='5589' column='1'/>
- <parameter type-id='5f8a1ac4' name='in_mask' filepath='kernel/sched/core.c' line='5589' column='1'/>
+ <function-decl name='sched_setaffinity' mangled-name='sched_setaffinity' filepath='kernel/sched/core.c' line='5597' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_setaffinity'>
+ <parameter type-id='587f89d2' name='pid' filepath='kernel/sched/core.c' line='5597' column='1'/>
+ <parameter type-id='5f8a1ac4' name='in_mask' filepath='kernel/sched/core.c' line='5597' column='1'/>
<return type-id='bd54fe1a'/>
</function-decl>
<function-decl name='strnlen' filepath='arch/arm64/include/asm/string.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'>
@@ -116900,21 +116901,21 @@
<parameter type-id='7359adad'/>
<return type-id='26a90f95'/>
</function-decl>
- <function-decl name='sched_isolate_cpu' mangled-name='sched_isolate_cpu' filepath='kernel/sched/core.c' line='6816' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_isolate_cpu'>
- <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6816' column='1'/>
+ <function-decl name='sched_isolate_cpu' mangled-name='sched_isolate_cpu' filepath='kernel/sched/core.c' line='6824' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_isolate_cpu'>
+ <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6824' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='sched_unisolate_cpu_unlocked' mangled-name='sched_unisolate_cpu_unlocked' filepath='kernel/sched/core.c' line='6894' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_unisolate_cpu_unlocked'>
- <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6894' column='1'/>
+ <function-decl name='sched_unisolate_cpu_unlocked' mangled-name='sched_unisolate_cpu_unlocked' filepath='kernel/sched/core.c' line='6902' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_unisolate_cpu_unlocked'>
+ <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6902' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='sched_unisolate_cpu' mangled-name='sched_unisolate_cpu' filepath='kernel/sched/core.c' line='6933' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_unisolate_cpu'>
- <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6933' column='1'/>
+ <function-decl name='sched_unisolate_cpu' mangled-name='sched_unisolate_cpu' filepath='kernel/sched/core.c' line='6941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='sched_unisolate_cpu'>
+ <parameter type-id='95e97e5e' name='cpu' filepath='kernel/sched/core.c' line='6941' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
- <function-decl name='set_task_boost' mangled-name='set_task_boost' filepath='kernel/sched/core.c' line='8648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_task_boost'>
- <parameter type-id='95e97e5e' name='boost' filepath='kernel/sched/core.c' line='8648' column='1'/>
- <parameter type-id='91ce1af9' name='period' filepath='kernel/sched/core.c' line='8648' column='1'/>
+ <function-decl name='set_task_boost' mangled-name='set_task_boost' filepath='kernel/sched/core.c' line='8656' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='set_task_boost'>
+ <parameter type-id='95e97e5e' name='boost' filepath='kernel/sched/core.c' line='8656' column='1'/>
+ <parameter type-id='91ce1af9' name='period' filepath='kernel/sched/core.c' line='8656' column='1'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='trace_print_flags_seq' mangled-name='trace_print_flags_seq' filepath='include/linux/trace_events.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='trace_print_flags_seq'>
@@ -127632,6 +127633,13 @@
<return type-id='26a90f95'/>
</function-decl>
</abi-instr>
+ <abi-instr address-size='64' path='lib/usercopy.c' language='LANG_C89'>
+ <function-decl name='check_zeroed_user' mangled-name='check_zeroed_user' filepath='lib/usercopy.c' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='check_zeroed_user'>
+ <parameter type-id='eaa32e2f' name='from' filepath='lib/usercopy.c' line='50' column='1'/>
+ <parameter type-id='b59d7dce' name='size' filepath='lib/usercopy.c' line='50' column='1'/>
+ <return type-id='95e97e5e'/>
+ </function-decl>
+ </abi-instr>
<abi-instr address-size='64' path='lib/vsprintf.c' language='LANG_C89'>
<function-decl name='vsnprintf' mangled-name='vsnprintf' filepath='lib/vsprintf.c' line='2274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='vsnprintf'>
<parameter type-id='26a90f95' name='buf' filepath='lib/vsprintf.c' line='2274' column='1'/>
@@ -146472,6 +146480,11 @@
<abi-instr address-size='64' path='drivers/gpu/msm/adreno_trace.c' language='LANG_C89'>
</abi-instr>
<abi-instr address-size='64' path='drivers/gpu/msm/kgsl.c' language='LANG_C89'>
+ <function-decl name='check_zeroed_user' filepath='include/linux/uaccess.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64'>
+ <parameter type-id='eaa32e2f'/>
+ <parameter type-id='7359adad'/>
+ <return type-id='95e97e5e'/>
+ </function-decl>
<function-decl name='arch_setup_dma_ops' filepath='arch/arm64/include/asm/dma-mapping.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64'>
<parameter type-id='fa0b179b'/>
<parameter type-id='3a47d82b'/>
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index c5bd9a7..7f64ac3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -571,6 +571,7 @@
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
u8 spectre_bhb_loop_affected(int scope);
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index deb4032..6936b21 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -85,6 +85,13 @@
#define ARM_CPU_PART_KRYO2XX_GOLD 0x800
#define ARM_CPU_PART_KRYO2XX_SILVER 0x801
#define ARM_CPU_PART_CORTEX_A77 0xD0D
+#define ARM_CPU_PART_NEOVERSE_V1 0xD40
+#define ARM_CPU_PART_CORTEX_A78 0xD41
+#define ARM_CPU_PART_CORTEX_X1 0xD44
+#define ARM_CPU_PART_CORTEX_A710 0xD47
+#define ARM_CPU_PART_CORTEX_X2 0xD48
+#define ARM_CPU_PART_NEOVERSE_N2 0xD49
+#define ARM_CPU_PART_CORTEX_A78C 0xD4B
#define ARM_CPU_PART_NEOVERSE_N1 0xD0C
#define ARM_CPU_PART_NEOVERSE_V1 0xD40
#define ARM_CPU_PART_CORTEX_A78 0xD41
@@ -123,6 +130,13 @@
#define MIDR_KRYO4G MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO4G)
#define MIDR_KRYO5S MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO5S)
#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
+#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
+#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
+#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
+#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
+#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index dfef42b..fdb5bab 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -909,6 +909,13 @@
.matches = has_ssbd_mitigation,
.midr_range_list = arm64_ssb_cpus,
},
+ {
+ .desc = "Spectre-BHB",
+ .capability = ARM64_SPECTRE_BHB,
+ .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+ .matches = is_spectre_bhb_affected,
+ .cpu_enable = spectre_bhb_enable_mitigation,
+ },
#ifdef CONFIG_ARM64_ERRATUM_1188873
{
.desc = "ARM erratum 1188873",
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index ea2ebef..4355dc2 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -31,6 +31,16 @@
#include <asm/cputype.h>
#include <asm/topology.h>
+/*
+ * This function returns the logic cpu number of the node.
+ * There are basically three kinds of return values:
+ * (1) logic cpu number which is > 0.
+ * (2) -ENODEV when the device tree(DT) node is valid and found in the DT but
+ * there is no possible logical CPU in the kernel to match. This happens
+ * when CONFIG_NR_CPUS is configure to be smaller than the number of
+ * CPU nodes in DT. We need to just ignore this case.
+ * (3) -1 if the node does not exist in the device tree
+ */
static int __init get_cpu_for_node(struct device_node *node)
{
struct device_node *cpu_node;
@@ -44,8 +54,8 @@
if (cpu >= 0)
topology_parse_cpu_capacity(cpu_node, cpu);
else
- pr_crit("Unable to find CPU node for %pOF\n", cpu_node);
-
+ pr_info("CPU node for %pOF exist but the possible cpu range is :%*pbl\n",
+ cpu_node, cpumask_pr_args(cpu_possible_mask));
of_node_put(cpu_node);
return cpu;
}
@@ -69,7 +79,7 @@
cpu_topology[cpu].package_id = package_id;
cpu_topology[cpu].core_id = core_id;
cpu_topology[cpu].thread_id = i;
- } else {
+ } else if (cpu != -ENODEV) {
pr_err("%pOF: Can't get CPU for thread\n",
t);
of_node_put(t);
@@ -90,7 +100,7 @@
cpu_topology[cpu].package_id = package_id;
cpu_topology[cpu].core_id = core_id;
- } else if (leaf) {
+ } else if (leaf && cpu != -ENODEV) {
pr_err("%pOF: Can't get CPU for leaf core\n", core);
return -EINVAL;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index df3a59b..b79dcd1 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1488,8 +1488,11 @@
spin_lock(&fl->hlock);
hlist_add_head(&ctx->hn, &clst->pending);
- cid = (fl->cid >= ADSP_DOMAIN_ID && fl->cid < NUM_CHANNELS)
- ? fl->cid : 0;
+ if (!(fl->cid >= ADSP_DOMAIN_ID && fl->cid < NUM_CHANNELS)) {
+ err = -ECHRNG;
+ goto bail;
+ }
+ cid = fl->cid;
chan = &me->channel[cid];
spin_unlock(&fl->hlock);
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index e98b9f3..f052eae 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -506,7 +506,7 @@
static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
{
- u32 cfg, mask;
+ u32 cfg, mask, d_val, not2d_val, n_minus_m;
struct clk_hw *hw = &rcg->clkr.hw;
int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
@@ -525,8 +525,17 @@
if (ret)
return ret;
+ /* Calculate 2d value */
+ d_val = f->n;
+
+ n_minus_m = f->n - f->m;
+ n_minus_m *= 2;
+
+ d_val = clamp_t(u32, d_val, f->m, n_minus_m);
+ not2d_val = ~d_val & mask;
+
ret = regmap_update_bits(rcg->clkr.regmap,
- rcg->cmd_rcgr + D_REG, mask, ~f->n);
+ rcg->cmd_rcgr + D_REG, mask, not2d_val);
if (ret)
return ret;
}
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 4cee427..a8b8166 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -2038,7 +2038,9 @@
goto exit_free_qcedev_areq;
}
- if (map_buf.num_fds > QCEDEV_MAX_BUFFERS) {
+ if (map_buf.num_fds > ARRAY_SIZE(map_buf.fd)) {
+ pr_err("%s: err: num_fds = %d exceeds max value\n",
+ __func__, map_buf.num_fds);
err = -EINVAL;
goto exit_free_qcedev_areq;
}
@@ -2078,6 +2080,12 @@
err = -EFAULT;
goto exit_free_qcedev_areq;
}
+ if (unmap_buf.num_fds > ARRAY_SIZE(unmap_buf.fd)) {
+ pr_err("%s: err: num_fds = %d exceeds max value\n",
+ __func__, unmap_buf.num_fds);
+ err = -EINVAL;
+ goto exit_free_qcedev_areq;
+ }
for (i = 0; i < unmap_buf.num_fds; i++) {
err = qcedev_check_and_unmap_buffer(handle,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7aedc24..b2cadc2 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2241,7 +2241,7 @@
cmdlist = u64_to_user_ptr(param->cmdlist);
/* Create a draw object for KGSL_GPU_AUX_COMMAND_TIMELINE */
- if (kgsl_copy_struct_from_user(&generic, sizeof(generic),
+ if (copy_struct_from_user(&generic, sizeof(generic),
cmdlist, param->cmdsize)) {
ret = -EFAULT;
goto err;
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 5759bb9..caaf381 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2002,2007-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __KGSL_DEVICE_H
#define __KGSL_DEVICE_H
@@ -17,73 +18,6 @@
[_IOC_NR((_cmd))] = \
{ .cmd = (_cmd), .func = (_func) }
-/**
- * kgsl_copy_struct_from_user: copy a struct from userspace
- * @dst: Destination address, in kernel space. This buffer must be @ksize
- * bytes long.
- * @ksize: Size of @dst struct.
- * @src: Source address, in userspace.
- * @usize: (Alleged) size of @src struct.
- *
- * Copies a struct from userspace to kernel space, in a way that guarantees
- * backwards-compatibility for struct syscall arguments (as long as future
- * struct extensions are made such that all new fields are *appended* to the
- * old struct, and zeroed-out new fields have the same meaning as the old
- * struct).
- *
- * @ksize is just sizeof(*dst), and @usize should've been passed by userspace.
- * The recommended usage is something like the following:
- *
- * SYSCALL_DEFINE2(foobar, const struct foo __user *, uarg, size_t, usize)
- * {
- * int err;
- * struct foo karg = {};
- *
- * if (usize > PAGE_SIZE)
- * return -E2BIG;
- * if (usize < FOO_SIZE_VER0)
- * return -EINVAL;
- *
- * err = kgsl_copy_struct_from_user(&karg, sizeof(karg), uarg, usize);
- * if (err)
- * return err;
- *
- * // ...
- * }
- *
- * There are three cases to consider:
- * * If @usize == @ksize, then it's copied verbatim.
- * * If @usize < @ksize, then the userspace has passed an old struct to a
- * newer kernel. The rest of the trailing bytes in @dst (@ksize - @usize)
- * are to be zero-filled.
- * * If @usize > @ksize, then the userspace has passed a new struct to an
- * older kernel. The trailing bytes unknown to the kernel (@usize - @ksize)
- * are checked to ensure they are zeroed, otherwise -E2BIG is returned.
- *
- * Returns (in all cases, some data may have been copied):
- * * -E2BIG: (@usize > @ksize) and there are non-zero trailing bytes in @src.
- * * -EFAULT: access to userspace failed.
- */
-static __always_inline __must_check int
-kgsl_copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
- size_t usize)
-{
- size_t size = min(ksize, usize);
- size_t rest = max(ksize, usize) - size;
-
- /* Deal with trailing bytes. */
- if (usize < ksize) {
- memset(dst + size, 0, rest);
- } else if (usize > ksize) {
- if (memchr_inv(src + size, 0, rest))
- return -E2BIG;
- }
- /* Copy the interoperable parts of the struct. */
- if (copy_from_user(dst, src, size))
- return -EFAULT;
- return 0;
-}
-
/*
* KGSL device state is initialized to INIT when platform_probe *
* successfully initialized the device. Once a device has been opened *
diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c
index 89cf478..fc53176 100644
--- a/drivers/gpu/msm/kgsl_drawobj.c
+++ b/drivers/gpu/msm/kgsl_drawobj.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/*
@@ -453,7 +454,7 @@
for (i = 0; i < count; i++, uptr += usize) {
struct kgsl_timeline_val val;
- if (kgsl_copy_struct_from_user(&val, sizeof(val), uptr, usize))
+ if (copy_struct_from_user(&val, sizeof(val), uptr, usize))
continue;
priv[i].timeline = val.timeline;
@@ -476,7 +477,7 @@
unsigned int id;
int ret;
- if (kgsl_copy_struct_from_user(&sync, sizeof(sync), uptr, usize))
+ if (copy_struct_from_user(&sync, sizeof(sync), uptr, usize))
return -EFAULT;
fence = kgsl_timelines_to_fence_array(device, sync.timelines,
@@ -535,7 +536,7 @@
struct event_fence_info *priv;
unsigned int id, i;
- if (kgsl_copy_struct_from_user(&sync, sizeof(sync), data, datasize))
+ if (copy_struct_from_user(&sync, sizeof(sync), data, datasize))
return -EFAULT;
kref_get(&drawobj->refcount);
@@ -665,7 +666,7 @@
{
struct kgsl_cmd_syncpoint_timestamp timestamp;
- if (kgsl_copy_struct_from_user(×tamp, sizeof(timestamp),
+ if (copy_struct_from_user(×tamp, sizeof(timestamp),
data, datasize))
return -EFAULT;
@@ -864,7 +865,7 @@
struct kgsl_gpu_aux_command_timeline cmd;
int i, ret;
- if (kgsl_copy_struct_from_user(&cmd, sizeof(cmd), src, cmdsize))
+ if (copy_struct_from_user(&cmd, sizeof(cmd), src, cmdsize))
return -EFAULT;
if (!cmd.count)
@@ -881,7 +882,7 @@
for (i = 0; i < cmd.count; i++) {
struct kgsl_timeline_val val;
- if (kgsl_copy_struct_from_user(&val, sizeof(val), src,
+ if (copy_struct_from_user(&val, sizeof(val), src,
cmd.timelines_size)) {
ret = -EFAULT;
goto err;
diff --git a/drivers/gpu/msm/kgsl_timeline.c b/drivers/gpu/msm/kgsl_timeline.c
index 897fe61..1143c9e 100644
--- a/drivers/gpu/msm/kgsl_timeline.c
+++ b/drivers/gpu/msm/kgsl_timeline.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/dma-fence.h>
@@ -41,7 +42,7 @@
struct kgsl_timeline_val val;
struct kgsl_timeline *timeline;
- if (kgsl_copy_struct_from_user(&val, sizeof(val),
+ if (copy_struct_from_user(&val, sizeof(val),
uptr, usize)) {
ret = -EFAULT;
goto err;
@@ -489,7 +490,7 @@
struct kgsl_timeline *timeline;
struct kgsl_timeline_val val;
- if (kgsl_copy_struct_from_user(&val, sizeof(val),
+ if (copy_struct_from_user(&val, sizeof(val),
u64_to_user_ptr(timelines), param->timelines_size))
return -EFAULT;
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index c00aa14..72795a5 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -319,6 +319,7 @@
bool hdrm_auto_mode_en;
bool thermal_derate_en;
bool otst_ramp_bkup_en;
+ bool torch_realtime_brightness_control;
};
/*
@@ -1338,7 +1339,7 @@
static void qpnp_flash_led_node_set(struct flash_node_data *fnode, int value)
{
- int i = 0;
+ int i = 0, val, rc = 0, addr_offset;
int prgm_current_ma = value;
int min_ma = fnode->ires_ua / 1000;
struct qpnp_flash_led *led = dev_get_drvdata(&fnode->pdev->dev);
@@ -1384,6 +1385,31 @@
if (led->total_current_ma >= 1000)
led->trigger_chgr = true;
}
+
+ if (led->pdata->torch_realtime_brightness_control) {
+ val = 0;
+ for (i = 0; i < led->num_fnodes; i++)
+ if (led->fnode[i].led_on)
+ val |= led->fnode[i].ires_idx <<
+ (led->fnode[i].id * 2);
+
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_IRES(led->base),
+ FLASH_LED_CURRENT_MASK, val);
+ if (rc < 0)
+ return;
+ for (i = 0; i < led->num_fnodes; i++) {
+ if (led->fnode[i].led_on) {
+ addr_offset = led->fnode[i].id;
+ rc = qpnp_flash_led_masked_write(led,
+ FLASH_LED_REG_TGR_CURRENT(led->base +
+ addr_offset), FLASH_LED_CURRENT_MASK,
+ led->fnode[i].current_reg_val);
+ if (rc < 0)
+ return;
+ }
+ }
+ }
}
static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
@@ -2920,6 +2946,9 @@
led->pdata->hdrm_auto_mode_en = of_property_read_bool(node,
"qcom,hdrm-auto-mode");
+ led->pdata->torch_realtime_brightness_control = of_property_read_bool(
+ node,
+ "qcom,torch-realtime-brightness-control");
rc = qpnp_flash_led_isc_delay_dt(led, node);
if (rc < 0)
return rc;
diff --git a/drivers/media/platform/msm/cvp/cvp_hfi.c b/drivers/media/platform/msm/cvp/cvp_hfi.c
index bb520c1..5492496 100644
--- a/drivers/media/platform/msm/cvp/cvp_hfi.c
+++ b/drivers/media/platform/msm/cvp/cvp_hfi.c
@@ -2931,6 +2931,7 @@
dprintk(CVP_WARN, "Skip PC(%#x, %#x, %#x)\n",
wfi_status, idle_status, pc_ready);
__flush_debug_queue(device, device->raw_packet);
+ __dsp_resume(device, 0);
return -EAGAIN;
}
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 998ce71..7080189 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2096,6 +2096,71 @@
u32 meta_format;
};
+/* ------------------------------------------------------------------------
+ * set urb queue size and urb packet size
+ *
+ */
+static ssize_t store_urb_config(struct device *dev,
+ struct device_attribute *attr, const char *buff, size_t count)
+{
+ struct uvc_streaming *stream;
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct uvc_device *udev = usb_get_intfdata(intf);
+ long max_urb, max_urb_packets;
+ int ret;
+ char *arr, *tmp;
+
+ arr = kstrdup(buff, GFP_KERNEL);
+
+ if (!arr)
+ return -ENOMEM;
+
+ tmp = strsep(&arr, ":");
+
+ if (!tmp)
+ return -EINVAL;
+
+ ret = kstrtol(tmp, 10, &max_urb);
+ if (ret < 0)
+ return ret;
+
+ tmp = strsep(&arr, ":");
+ if (!tmp)
+ return -EINVAL;
+
+ ret = kstrtol(tmp, 10, &max_urb_packets);
+ if (ret < 0)
+ return ret;
+
+ if (max_urb <= 0 || max_urb > 128 ||
+ max_urb_packets <= 0 || max_urb_packets > 128)
+ return -EINVAL;
+
+ list_for_each_entry(stream, &udev->streams, list) {
+ if (stream->refcnt)
+ continue;
+ stream->max_urb = max_urb;
+ stream->max_urb_packets = max_urb_packets;
+ }
+
+ return count;
+}
+
+static ssize_t show_urb_config(struct device *dev,
+ struct device_attribute *attr, char *buff)
+{
+ return 0;
+}
+
+static struct device_attribute urb_config_attr = {
+ .attr = {
+ .name = "urb_config",
+ .mode = 00660,
+ },
+ .show = show_urb_config,
+ .store = store_urb_config,
+};
+
static int uvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -2228,6 +2293,12 @@
uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
usb_enable_autosuspend(udev);
+
+ /* sysfs file for dynamically setting urb configs */
+ ret = sysfs_create_file(&dev->intf->dev.kobj, &urb_config_attr.attr);
+ if (ret != 0)
+ pr_info("Unable to initialize urb configuration: %d\n", ret);
+
return 0;
error:
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 853f22a..b1b514b 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1547,7 +1547,7 @@
{
unsigned int i;
- for (i = 0; i < UVC_URBS; ++i) {
+ for (i = 0; i < stream->max_urb; ++i) {
if (stream->urb_buffer[i]) {
#ifndef CONFIG_DMA_NONCOHERENT
usb_free_coherent(stream->dev->udev, stream->urb_size,
@@ -1587,12 +1587,22 @@
* payloads across multiple URBs.
*/
npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_PACKETS)
- npackets = UVC_MAX_PACKETS;
+ if (npackets > stream->max_urb_packets)
+ npackets = stream->max_urb_packets;
+
+
+ /* Allocate memory for storing URB pointers */
+ stream->urb = kcalloc(stream->max_urb,
+ sizeof(struct urb *), gfp_flags | __GFP_NOWARN);
+ stream->urb_buffer = kcalloc(stream->max_urb,
+ sizeof(char *), gfp_flags | __GFP_NOWARN);
+ stream->urb_dma = kcalloc(stream->max_urb,
+ sizeof(dma_addr_t), gfp_flags | __GFP_NOWARN);
+
/* Retry allocations until one succeed. */
for (; npackets > 1; npackets /= 2) {
- for (i = 0; i < UVC_URBS; ++i) {
+ for (i = 0; i < stream->max_urb; ++i) {
stream->urb_size = psize * npackets;
#ifndef CONFIG_DMA_NONCOHERENT
stream->urb_buffer[i] = usb_alloc_coherent(
@@ -1608,10 +1618,10 @@
}
}
- if (i == UVC_URBS) {
- uvc_trace(UVC_TRACE_VIDEO, "Allocated %u URB buffers "
- "of %ux%u bytes each.\n", UVC_URBS, npackets,
- psize);
+ if (i == stream->max_urb) {
+ uvc_trace(UVC_TRACE_VIDEO,
+ "Allocated %u URB buffers of %ux%u bytes each.\n",
+ stream->max_urb, npackets, psize);
return npackets;
}
}
@@ -1631,7 +1641,7 @@
uvc_video_stats_stop(stream);
- for (i = 0; i < UVC_URBS; ++i) {
+ for (i = 0; i < stream->max_urb; ++i) {
urb = stream->urb[i];
if (urb == NULL)
continue;
@@ -1643,6 +1653,8 @@
if (free_buffers)
uvc_free_urb_buffers(stream);
+
+ stream->refcnt--;
}
/*
@@ -1692,7 +1704,7 @@
size = npackets * psize;
- for (i = 0; i < UVC_URBS; ++i) {
+ for (i = 0; i < stream->max_urb; ++i) {
urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
uvc_uninit_video(stream, 1);
@@ -1758,7 +1770,7 @@
if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
size = 0;
- for (i = 0; i < UVC_URBS; ++i) {
+ for (i = 0; i < stream->max_urb; ++i) {
urb = usb_alloc_urb(0, gfp_flags);
if (urb == NULL) {
uvc_uninit_video(stream, 1);
@@ -1867,7 +1879,8 @@
return ret;
/* Submit the URBs. */
- for (i = 0; i < UVC_URBS; ++i) {
+ stream->refcnt++;
+ for (i = 0; i < stream->max_urb; ++i) {
ret = usb_submit_urb(stream->urb[i], gfp_flags);
if (ret < 0) {
uvc_printk(KERN_ERR, "Failed to submit URB %u "
@@ -2028,6 +2041,9 @@
stream->cur_format = format;
stream->cur_frame = frame;
+ stream->max_urb = UVC_URBS;
+ stream->max_urb_packets = UVC_MAX_PACKETS;
+
/* Select the video decoding function */
if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 839ba3c..a89f8ed 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -535,9 +535,9 @@
u32 max_payload_size;
} bulk;
- struct urb *urb[UVC_URBS];
- char *urb_buffer[UVC_URBS];
- dma_addr_t urb_dma[UVC_URBS];
+ struct urb **urb;
+ char **urb_buffer;
+ dma_addr_t *urb_dma;
unsigned int urb_size;
u32 sequence;
@@ -570,6 +570,15 @@
spinlock_t lock;
} clock;
+
+ /* Maximum number of URBs that can be submitted */
+ u32 max_urb;
+
+ /* Maximum number of packets per URB */
+ u32 max_urb_packets;
+
+ /*set if stream in progress */
+ u8 refcnt;
};
struct uvc_device {
diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c
index a824a19..66b2bbe 100644
--- a/drivers/net/wireless/cnss2/pci.c
+++ b/drivers/net/wireless/cnss2/pci.c
@@ -426,15 +426,25 @@
static void cnss_pci_select_window(struct cnss_pci_data *pci_priv, u32 offset)
{
u32 window = (offset >> WINDOW_SHIFT) & WINDOW_VALUE_MASK;
+ u32 window_enable = WINDOW_ENABLE_BIT | window;
+ u32 val;
- writel_relaxed(WINDOW_ENABLE_BIT | window,
- QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET +
- pci_priv->bar);
+ writel_relaxed(window_enable, pci_priv->bar +
+ QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET);
if (window != pci_priv->remap_window) {
pci_priv->remap_window = window;
cnss_pr_dbg("Config PCIe remap window register to 0x%x\n",
- WINDOW_ENABLE_BIT | window);
+ window_enable);
+ }
+
+ /* Read it back to make sure the write has taken effect */
+ val = readl_relaxed(pci_priv->bar + QCA6390_PCIE_REMAP_BAR_CTRL_OFFSET);
+ if (val != window_enable) {
+ cnss_pr_err("Failed to config window register to 0x%x, current value: 0x%x\n",
+ window_enable, val);
+ if (!cnss_pci_check_link_status(pci_priv))
+ CNSS_ASSERT(0);
}
}
diff --git a/drivers/perf/qcom_l2_counters.c b/drivers/perf/qcom_l2_counters.c
index d1c93f2..a7e71bc 100644
--- a/drivers/perf/qcom_l2_counters.c
+++ b/drivers/perf/qcom_l2_counters.c
@@ -1037,8 +1037,8 @@
struct cluster_pmu *cluster;
u32 fw_cluster_id;
struct resource res;
- int ret;
- int irq;
+ int ret = 0;
+ int irq, cpu, cpu_count = 0;
cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);
if (!cluster) {
@@ -1064,6 +1064,14 @@
goto err_put_dev;
}
+ for_each_possible_cpu(cpu) {
+ if (topology_physical_package_id(cpu) == fw_cluster_id) {
+ cpu_count++;
+ break;
+ }
+ }
+ if (cpu_count == 0)
+ goto err_put_dev;
ret = of_address_to_resource(cn, 0, &res);
if (ret) {
pr_err(L2_COUNTERS_BUG "not able to find the resource\n");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 88c2315..0f25eaa 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -2476,7 +2476,7 @@
spin_lock_bh(&sys->spinlock);
rx_pkt = list_first_entry(&sys->rcycl_list,
struct ipa3_rx_pkt_wrapper, link);
- list_del(&rx_pkt->link);
+ list_del_init(&rx_pkt->link);
spin_unlock_bh(&sys->spinlock);
ptr = skb_put(rx_pkt->data.skb, sys->rx_buff_sz);
rx_pkt->data.dma_addr = dma_map_single(ipa3_ctx->pdev,
@@ -2517,8 +2517,8 @@
goto done;
fail_dma_mapping:
spin_lock_bh(&sys->spinlock);
+ ipa3_skb_recycle(rx_pkt->data.skb);
list_add_tail(&rx_pkt->link, &sys->rcycl_list);
- INIT_LIST_HEAD(&rx_pkt->link);
spin_unlock_bh(&sys->spinlock);
fail_kmem_cache_alloc:
if (rx_len_cached == 0)
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen4.c b/drivers/power/supply/qcom/qpnp-fg-gen4.c
index 18cd57e..fcd26de 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen4.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen4.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "FG: %s: " fmt, __func__
@@ -30,12 +31,13 @@
#define FG_MEM_IF_PM8150B 0x0D
#define FG_ADC_RR_PM8150B 0x13
-#define SDAM_COOKIE_OFFSET 0x80
#define SDAM_CYCLE_COUNT_OFFSET 0x81
#define SDAM_CAP_LEARN_OFFSET 0x91
-#define SDAM_COOKIE 0xA5
#define SDAM_FG_PARAM_LENGTH 20
+#define SDAM_COOKIE_OFFSET_4BYTE 0x95
+#define SDAM_COOKIE_4BYTE 0x12345678
+
#define FG_SRAM_LEN 972
#define PROFILE_LEN 416
#define PROFILE_COMP_LEN 24
@@ -1302,7 +1304,7 @@
struct fg_dev *fg;
int16_t cc_mah;
int rc;
- u8 cookie = SDAM_COOKIE;
+ u32 cookie_4byte = SDAM_COOKIE_4BYTE;
if (!chip)
return -ENODEV;
@@ -1329,8 +1331,8 @@
return rc;
}
- rc = nvmem_device_write(chip->fg_nvmem, SDAM_COOKIE_OFFSET, 1,
- &cookie);
+ rc = nvmem_device_write(chip->fg_nvmem,
+ SDAM_COOKIE_OFFSET_4BYTE, 1, &cookie_4byte);
if (rc < 0) {
pr_err("Error in writing cookie to SDAM, rc=%d\n", rc);
return rc;
@@ -2377,17 +2379,17 @@
{
struct fg_dev *fg = &chip->fg;
int rc;
- u8 cookie;
+ u32 cookie_4byte;
- rc = nvmem_device_read(chip->fg_nvmem, SDAM_COOKIE_OFFSET, 1,
- &cookie);
+ rc = nvmem_device_read(chip->fg_nvmem, SDAM_COOKIE_OFFSET_4BYTE, 4,
+ &cookie_4byte);
if (rc < 0) {
pr_err("Error in reading SDAM_COOKIE rc=%d\n", rc);
return false;
}
- fg_dbg(fg, FG_STATUS, "cookie: %x\n", cookie);
- return (cookie == SDAM_COOKIE);
+ fg_dbg(fg, FG_STATUS, "cookie_4byte: %08x\n", cookie_4byte);
+ return (cookie_4byte == SDAM_COOKIE_4BYTE);
}
static void fg_gen4_clear_sdam(struct fg_gen4_chip *chip)
@@ -2411,8 +2413,9 @@
static void fg_gen4_post_profile_load(struct fg_gen4_chip *chip)
{
struct fg_dev *fg = &chip->fg;
- int rc, act_cap_mah;
+ int rc = 0, act_cap_mah;
u8 buf[16] = {0};
+ u32 cookie_4byte = 0;
if (chip->dt.multi_profile_load &&
chip->batt_age_level != chip->last_batt_age_level) {
@@ -2466,6 +2469,13 @@
pr_err("Error in writing learned capacity to SDAM, rc=%d\n",
rc);
}
+
+ /* Set the COOKIE to prevent rechecking the SRAM again */
+ cookie_4byte = SDAM_COOKIE_4BYTE;
+ rc = nvmem_device_write(chip->fg_nvmem,
+ SDAM_COOKIE_OFFSET_4BYTE, 4, (u8 *)&cookie_4byte);
+ if (rc < 0)
+ pr_err("Failed to set SDAM cookie, rc=%d\n", rc);
}
/* Restore the cycle counters so that it would be valid at this point */
diff --git a/drivers/soc/qcom/core_hang_detect.c b/drivers/soc/qcom/core_hang_detect.c
index 5196817..a45f8a8 100644
--- a/drivers/soc/qcom/core_hang_detect.c
+++ b/drivers/soc/qcom/core_hang_detect.c
@@ -238,10 +238,11 @@
struct device_node *cpu_node;
struct device_node *node = pdev->dev.of_node;
struct hang_detect *hang_det = NULL;
- int cpu, ret, cpu_count = 0;
+ int cpu, ret, cpu_count = 0, cluster_cpu_count = 0;
const char *name;
u32 treg[NR_CPUS] = {0}, creg[NR_CPUS] = {0};
u32 num_reg = 0;
+ u32 fw_cluster_id;
if (!pdev->dev.of_node || !enable)
return -ENODEV;
@@ -279,6 +280,27 @@
return -EINVAL;
}
+ ret = of_property_read_u32(node, "cluster-id", &fw_cluster_id);
+ if (ret) {
+ pr_err("%s: Missing cluster-id.\n", __func__);
+ } else {
+
+ for_each_possible_cpu(cpu) {
+ if (topology_physical_package_id(cpu)
+ == fw_cluster_id) {
+ cluster_cpu_count++;
+ break;
+ }
+ }
+
+ if (cluster_cpu_count == 0) {
+ pr_err("%s: Unable to find any CPU for cluster:%d\n",
+ __func__, fw_cluster_id);
+ return -EINVAL;
+ }
+
+ }
+
for_each_possible_cpu(cpu) {
cpu_node = of_get_cpu_node(cpu, NULL);
if (cpu_node == NULL)
diff --git a/drivers/soc/qcom/msm_performance.c b/drivers/soc/qcom/msm_performance.c
index 7430bb2..a5767b0 100644
--- a/drivers/soc/qcom/msm_performance.c
+++ b/drivers/soc/qcom/msm_performance.c
@@ -76,13 +76,15 @@
for (i = 0; i < ntokens; i += 2) {
if (sscanf(cp, "%u:%u", &cpu, &val) != 2)
return -EINVAL;
- if (cpu > (num_present_cpus() - 1))
- return -EINVAL;
+ if (cpu >= nr_cpu_ids)
+ break;
- i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu);
+ if (cpu_possible(cpu)) {
+ i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu);
- i_cpu_stats->min = val;
- cpumask_set_cpu(cpu, limit_mask);
+ i_cpu_stats->min = val;
+ cpumask_set_cpu(cpu, limit_mask);
+ }
cp = strnchr(cp, strlen(cp), ' ');
cp++;
@@ -153,14 +155,15 @@
for (i = 0; i < ntokens; i += 2) {
if (sscanf(cp, "%u:%u", &cpu, &val) != 2)
return -EINVAL;
- if (cpu > (num_present_cpus() - 1))
- return -EINVAL;
+ if (cpu >= nr_cpu_ids)
+ break;
- i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu);
+ if (cpu_possible(cpu)) {
+ i_cpu_stats = &per_cpu(msm_perf_cpu_stats, cpu);
- i_cpu_stats->max = val;
- cpumask_set_cpu(cpu, limit_mask);
-
+ i_cpu_stats->max = val;
+ cpumask_set_cpu(cpu, limit_mask);
+ }
cp = strnchr(cp, strlen(cp), ' ');
cp++;
}
diff --git a/drivers/soc/qcom/scm.c b/drivers/soc/qcom/scm.c
index 4d724e3..42e4e4f 100644
--- a/drivers/soc/qcom/scm.c
+++ b/drivers/soc/qcom/scm.c
@@ -678,6 +678,40 @@
}
EXPORT_SYMBOL(scm_is_secure_device);
+#define TZ_HLOS_NOTIFY_CORE_KERNEL_BOOTUP 0x7
+int scm_mem_protection_init_do_qrks(void)
+{
+ uint32_t pid_offset = 0;
+ uint32_t task_name_offset = 0;
+ struct scm_desc desc = {0};
+ int ret = 0, resp;
+
+ pid_offset = offsetof(struct task_struct, pid);
+ task_name_offset = offsetof(struct task_struct, comm);
+ pr_debug("offset of pid is %zu, offset of comm is %zu\n",
+ pid_offset, task_name_offset);
+ desc.args[0] = pid_offset;
+ desc.args[1] = task_name_offset;
+ desc.arginfo = 2;
+ ret = scm_call2(SCM_SIP_FNID(SCM_SVC_RTIC,
+ TZ_HLOS_NOTIFY_CORE_KERNEL_BOOTUP),
+ &desc);
+ resp = desc.ret[0];
+
+ if (ret == -1) {
+ pr_err("%s: SCM call not supported\n", __func__);
+ return ret;
+ } else if (ret || resp) {
+ pr_err("%s: SCM call failed\n", __func__);
+ if (ret)
+ return ret;
+ else
+ return resp;
+ }
+
+ return resp;
+}
+
/*
* SCM call command ID to protect kernel memory
* in Hyp Stage 2 page tables.
@@ -691,6 +725,7 @@
struct scm_desc desc = {0};
int ret = 0, resp;
+ scm_mem_protection_init_do_qrks();
desc.args[0] = 0;
desc.arginfo = 0;
ret = scm_call2(SCM_SIP_FNID(SCM_SVC_RTIC,
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index cbbca7f..b6bfc85 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -21,6 +21,7 @@
#include <soc/qcom/socinfo.h>
#include <linux/soc/qcom/smem.h>
#include "boot_stats.h"
+#include <asm/unaligned.h>
#define BUILD_ID_LENGTH 32
#define CHIP_ID_LENGTH 32
@@ -343,6 +344,7 @@
/* Khaje ID */
[518] = {MSM_CPU_KHAJE, "KHAJE"},
+ [586] = {MSM_CPU_KHAJE, "KHAJE"},
/* Khajep ID */
[561] = {MSM_CPU_KHAJEP, "KHAJEP"},
@@ -851,6 +853,42 @@
socinfo_get_ncluster_array_offset());
}
+uint32_t
+socinfo_get_cluster_info(enum defective_cluster_type cluster)
+{
+ uint32_t def_cluster, num_cluster, offset;
+ void *cluster_val;
+ void *info = socinfo;
+
+ if (cluster >= NUM_CLUSTERS_MAX) {
+ pr_err("Bad cluster\n");
+ return -EINVAL;
+ }
+
+ num_cluster = socinfo_get_num_clusters();
+ offset = socinfo_get_ncluster_array_offset();
+
+ if (!num_cluster || !offset)
+ return -EINVAL;
+
+ info += offset;
+ cluster_val = info + (sizeof(uint32_t) * cluster);
+ def_cluster = get_unaligned_le32(cluster_val);
+
+ return def_cluster;
+}
+EXPORT_SYMBOL(socinfo_get_cluster_info);
+
+static ssize_t
+msm_get_defective_cores(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ uint32_t def_cluster = socinfo_get_cluster_info(CLUSTER_CPUSS);
+
+ return scnprintf(buf, PAGE_SIZE, "%x\n", def_cluster);
+}
+
static ssize_t
msm_get_num_defective_parts(struct device *dev,
struct device_attribute *attr,
@@ -869,6 +907,60 @@
socinfo_get_ndefective_parts_array_offset());
}
+static uint32_t
+socinfo_get_defective_parts(void)
+{
+ uint32_t num_parts = socinfo_get_num_defective_parts();
+ uint32_t offset = socinfo_get_ndefective_parts_array_offset();
+ uint32_t def_parts = 0;
+ void *info = socinfo;
+ uint32_t part_entry;
+ int i;
+
+ if (!num_parts || !offset)
+ return -EINVAL;
+
+ info += offset;
+ for (i = 0; i < num_parts; i++) {
+ part_entry = get_unaligned_le32(info);
+ if (part_entry)
+ def_parts |= BIT(i);
+ info += sizeof(uint32_t);
+ }
+
+ return def_parts;
+}
+
+bool
+socinfo_get_part_info(enum defective_part_type part)
+{
+ uint32_t partinfo;
+
+ if (part >= NUM_PARTS_MAX) {
+ pr_err("Bad part number\n");
+ return false;
+ }
+
+ partinfo = socinfo_get_defective_parts();
+ if (partinfo < 0) {
+ pr_err("Failed to get part information\n");
+ return false;
+ }
+
+ return (partinfo & BIT(part));
+}
+EXPORT_SYMBOL(socinfo_get_part_info);
+
+static ssize_t
+msm_get_defective_parts(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ uint32_t def_parts = socinfo_get_defective_parts();
+
+ return scnprintf(buf, PAGE_SIZE, "%x\n", def_parts);
+}
+
static ssize_t
msm_get_nmodem_supported(struct device *dev,
struct device_attribute *attr,
@@ -1206,6 +1298,10 @@
__ATTR(ncluster_array_offset, 0444,
msm_get_ncluster_array_offset, NULL);
+static struct device_attribute msm_soc_attr_defective_cores =
+ __ATTR(defective_cores, 0444,
+ msm_get_defective_cores, NULL);
+
static struct device_attribute msm_soc_attr_num_defective_parts =
__ATTR(num_defective_parts, 0444,
msm_get_num_defective_parts, NULL);
@@ -1214,6 +1310,10 @@
__ATTR(ndefective_parts_array_offset, 0444,
msm_get_ndefective_parts_array_offset, NULL);
+static struct device_attribute msm_soc_attr_defective_parts =
+ __ATTR(defective_parts, 0444,
+ msm_get_defective_parts, NULL);
+
static struct device_attribute msm_soc_attr_nmodem_supported =
__ATTR(nmodem_supported, 0444,
msm_get_nmodem_supported, NULL);
@@ -1430,9 +1530,13 @@
device_create_file(msm_soc_device,
&msm_soc_attr_ncluster_array_offset);
device_create_file(msm_soc_device,
+ &msm_soc_attr_defective_cores);
+ device_create_file(msm_soc_device,
&msm_soc_attr_num_defective_parts);
device_create_file(msm_soc_device,
&msm_soc_attr_ndefective_parts_array_offset);
+ device_create_file(msm_soc_device,
+ &msm_soc_attr_defective_parts);
case SOCINFO_VERSION(0, 13):
device_create_file(msm_soc_device,
&msm_soc_attr_nproduct_id);
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index c81d6dbd..16b329b 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#if defined(CONFIG_SERIAL_MSM_GENI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -2390,15 +2391,7 @@
if (!uart_console(uport)) {
/* For now only assume FIFO mode. */
msm_port->xfer_mode = SE_DMA;
- se_get_packing_config(8, 4, false, &cfg0, &cfg1);
- geni_write_reg_nolog(cfg0, uport->membase,
- SE_GENI_TX_PACKING_CFG0);
- geni_write_reg_nolog(cfg1, uport->membase,
- SE_GENI_TX_PACKING_CFG1);
- geni_write_reg_nolog(cfg0, uport->membase,
- SE_GENI_RX_PACKING_CFG0);
- geni_write_reg_nolog(cfg1, uport->membase,
- SE_GENI_RX_PACKING_CFG1);
+ se_config_packing(uport->membase, 8, 4, false);
if (!msm_port->rx_fifo) {
ret = -ENOMEM;
goto exit_portsetup;
@@ -2554,6 +2547,8 @@
SE_UART_RX_WORD_LEN);
geni_write_reg_nolog(stop_bit_len, uport->membase,
SE_UART_TX_STOP_BIT_LEN);
+ if (!uart_console(uport))
+ se_config_packing(uport->membase, bits_per_char, 4, false);
geni_write_reg_nolog(s_clk_cfg, uport->membase, GENI_SER_M_CLK_CFG);
geni_write_reg_nolog(s_clk_cfg, uport->membase, GENI_SER_S_CLK_CFG);
geni_read_reg_nolog(uport->membase, GENI_SER_M_CLK_CFG);
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 58d9af2..102cd62 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -1340,10 +1340,13 @@
{
struct ffs_epfile *epfile = inode->i_private;
struct ffs_data *ffs = epfile->ffs;
+ unsigned long flags;
ENTER();
+ spin_lock_irqsave(&epfile->ffs->eps_lock, flags);
__ffs_epfile_read_buffer_free(epfile);
+ spin_unlock_irqrestore(&epfile->ffs->eps_lock, flags);
ffs_log("%s: state %d setup_state %d flag %lu opened %u",
epfile->name, epfile->ffs->state, epfile->ffs->setup_state,
epfile->ffs->flags, atomic_read(&epfile->opened));
@@ -1946,9 +1949,14 @@
ffs->ffs_eventfd = NULL;
}
+ mutex_lock(&ffs->mutex);
kfree(ffs->raw_descs_data);
+ ffs->raw_descs_data = NULL;
kfree(ffs->raw_strings);
+ ffs->raw_strings = NULL;
kfree(ffs->stringtabs);
+ ffs->stringtabs = NULL;
+ mutex_unlock(&ffs->mutex);
}
static void ffs_data_reset(struct ffs_data *ffs)
@@ -1960,10 +1968,7 @@
ffs_data_clear(ffs);
- ffs->raw_descs_data = NULL;
ffs->raw_descs = NULL;
- ffs->raw_strings = NULL;
- ffs->stringtabs = NULL;
ffs->raw_descs_length = 0;
ffs->fs_descs_count = 0;
@@ -2143,14 +2148,15 @@
unsigned long flags;
int ret = 0;
- ffs_log("enter: state %d setup_state %d flag %lu", func->ffs->state,
- func->ffs->setup_state, func->ffs->flags);
-
spin_lock_irqsave(&func->ffs->eps_lock, flags);
ffs = func->ffs;
ep = func->eps;
epfile = ffs->epfiles;
count = ffs->eps_count;
+
+ ffs_log("enter: state %d setup_state %d flag %lu", func->ffs->state,
+ func->ffs->setup_state, func->ffs->flags);
+
while(count--) {
ep->ep->driver_data = ep;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index d98cf7e..f4c2e45 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -714,11 +714,19 @@
return create_new_entry(fc, &args, dir, entry, S_IFLNK);
}
+void fuse_flush_time_update(struct inode *inode)
+{
+ int err = sync_inode_metadata(inode, 1);
+
+ mapping_set_error(inode->i_mapping, err);
+}
+
void fuse_update_ctime(struct inode *inode)
{
if (!IS_NOCMTIME(inode)) {
inode->i_ctime = current_time(inode);
mark_inode_dirty_sync(inode);
+ fuse_flush_time_update(inode);
}
}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d4961fa9..53ffd05 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1643,6 +1643,17 @@
struct fuse_file *ff;
int err;
+ /*
+ * Inode is always written before the last reference is dropped and
+ * hence this should not be reached from reclaim.
+ *
+ * Writing back the inode from reclaim can deadlock if the request
+ * processing itself needs an allocation. Allocations triggering
+ * reclaim while serving a request can't be prevented, because it can
+ * involve any number of unrelated userspace processes.
+ */
+ WARN_ON(wbc->for_reclaim);
+
ff = __fuse_write_file_get(fc, fi);
err = fuse_flush_times(inode, ff);
if (ff)
@@ -3062,6 +3073,8 @@
if (lock_inode)
inode_unlock(inode);
+ fuse_flush_time_update(inode);
+
return err;
}
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 058f0f6..dec2e1f 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -962,6 +962,7 @@
u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
+void fuse_flush_time_update(struct inode *inode);
void fuse_update_ctime(struct inode *inode);
int fuse_update_attributes(struct inode *inode, struct file *file);
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d9b41ee..9754c43 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -128,6 +128,9 @@
static void fuse_evict_inode(struct inode *inode)
{
+ /* Will write inode on close/munmap and in all other dirtiers */
+ WARN_ON(inode->i_state & I_DIRTY_INODE);
+
truncate_inode_pages_final(&inode->i_data);
clear_inode(inode);
if (inode->i_sb->s_flags & SB_ACTIVE) {
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 5c1522e..96b9bfa 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -4,6 +4,13 @@
#include <asm/types.h>
#include <linux/bits.h>
+/* Set bits in the first 'n' bytes when loaded from memory */
+#ifdef __LITTLE_ENDIAN
+# define aligned_byte_mask(n) ((1UL << 8*(n))-1)
+#else
+# define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
+#endif
+
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 1a5b23a..e8c32ae 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -230,6 +230,76 @@
#endif /* ARCH_HAS_NOCACHE_UACCESS */
+extern __must_check int check_zeroed_user(const void __user *from, size_t size);
+
+/**
+ * copy_struct_from_user: copy a struct from userspace
+ * @dst: Destination address, in kernel space. This buffer must be @ksize
+ * bytes long.
+ * @ksize: Size of @dst struct.
+ * @src: Source address, in userspace.
+ * @usize: (Alleged) size of @src struct.
+ *
+ * Copies a struct from userspace to kernel space, in a way that guarantees
+ * backwards-compatibility for struct syscall arguments (as long as future
+ * struct extensions are made such that all new fields are *appended* to the
+ * old struct, and zeroed-out new fields have the same meaning as the old
+ * struct).
+ *
+ * @ksize is just sizeof(*dst), and @usize should've been passed by userspace.
+ * The recommended usage is something like the following:
+ *
+ * SYSCALL_DEFINE2(foobar, const struct foo __user *, uarg, size_t, usize)
+ * {
+ * int err;
+ * struct foo karg = {};
+ *
+ * if (usize > PAGE_SIZE)
+ * return -E2BIG;
+ * if (usize < FOO_SIZE_VER0)
+ * return -EINVAL;
+ *
+ * err = copy_struct_from_user(&karg, sizeof(karg), uarg, usize);
+ * if (err)
+ * return err;
+ *
+ * // ...
+ * }
+ *
+ * There are three cases to consider:
+ * * If @usize == @ksize, then it's copied verbatim.
+ * * If @usize < @ksize, then the userspace has passed an old struct to a
+ * newer kernel. The rest of the trailing bytes in @dst (@ksize - @usize)
+ * are to be zero-filled.
+ * * If @usize > @ksize, then the userspace has passed a new struct to an
+ * older kernel. The trailing bytes unknown to the kernel (@usize - @ksize)
+ * are checked to ensure they are zeroed, otherwise -E2BIG is returned.
+ *
+ * Returns (in all cases, some data may have been copied):
+ * * -E2BIG: (@usize > @ksize) and there are non-zero trailing bytes in @src.
+ * * -EFAULT: access to userspace failed.
+ */
+static __always_inline __must_check int
+copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
+ size_t usize)
+{
+ size_t size = min(ksize, usize);
+ size_t rest = max(ksize, usize) - size;
+
+ /* Deal with trailing bytes. */
+ if (usize < ksize) {
+ memset(dst + size, 0, rest);
+ } else if (usize > ksize) {
+ int ret = check_zeroed_user(src + size, rest);
+ if (ret <= 0)
+ return ret ?: -E2BIG;
+ }
+ /* Copy the interoperable parts of the struct. */
+ if (copy_from_user(dst, src, size))
+ return -EFAULT;
+ return 0;
+}
+
/*
* probe_kernel_read(): safely attempt to read from a location
* @dst: pointer to the buffer that shall take the data
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index 7426987..0effccf 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -307,6 +307,30 @@
PMIC_MODEL_UNKNOWN = 0xFFFFFFFF
};
+enum defective_part_type {
+ PART_UNKNOWN = 0,
+ PART_GPU = 1,
+ PART_VIDEO = 2,
+ PART_CAMERA = 3,
+ PART_DISPLAY = 4,
+ PART_AUDIO = 5,
+ PART_MODEM = 6,
+ PART_WLAN = 7,
+ PART_COMP = 8,
+ PART_SENSORS = 9,
+ PART_NPU = 10,
+ PART_SPSS = 11,
+ PART_NAV = 12,
+ PART_COMP1 = 13,
+ PART_DISPLAY1 = 14,
+ NUM_PARTS_MAX,
+};
+
+enum defective_cluster_type {
+ CLUSTER_CPUSS = 0,
+ NUM_CLUSTERS_MAX,
+};
+
enum msm_cpu socinfo_get_msm_cpu(void);
uint32_t socinfo_get_id(void);
uint32_t socinfo_get_version(void);
@@ -320,6 +344,8 @@
uint32_t socinfo_get_g_platform_subtype(void);
uint32_t socinfo_get_g_platform_version(void);
uint32_t socinfo_get_serial_number(void);
+uint32_t socinfo_get_cluster_info(enum defective_cluster_type cluster);
+bool socinfo_get_part_info(enum defective_part_type part);
enum pmic_model socinfo_get_pmic_model(void);
uint32_t socinfo_get_pmic_die_revision(void);
int __init socinfo_init(void) __must_check;
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 4469d32..f396037 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -1582,6 +1582,9 @@
#define V4L2_CID_MPEG_VIDC_VIDEO_IR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE+166)
+#define V4L2_CID_MPEG_VIDC_ENABLE_ONLY_BASE_LAYER_IR \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 167)
+
enum v4l2_mpeg_vidc_video_mbi_statistics_mode {
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_DEFAULT = 0,
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_1 = 1,
diff --git a/include/uapi/media/msm_camsensor_sdk.h b/include/uapi/media/msm_camsensor_sdk.h
index 950ecf7..35014ac 100644
--- a/include/uapi/media/msm_camsensor_sdk.h
+++ b/include/uapi/media/msm_camsensor_sdk.h
@@ -62,6 +62,8 @@
CAMERA_1,
CAMERA_2,
CAMERA_3,
+ CAMERA_4,
+ CAMERA_5,
MAX_CAMERAS,
};
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c
index 37628e7..d197884 100644
--- a/lib/strnlen_user.c
+++ b/lib/strnlen_user.c
@@ -3,16 +3,10 @@
#include <linux/export.h>
#include <linux/uaccess.h>
#include <linux/mm.h>
+#include <linux/bitops.h>
#include <asm/word-at-a-time.h>
-/* Set bits in the first 'n' bytes when loaded from memory */
-#ifdef __LITTLE_ENDIAN
-# define aligned_byte_mask(n) ((1ul << 8*(n))-1)
-#else
-# define aligned_byte_mask(n) (~0xfful << (BITS_PER_LONG - 8 - 8*(n)))
-#endif
-
/*
* Do a strnlen, return length of string *with* final '\0'.
* 'count' is the user-supplied count, while 'max' is the
diff --git a/lib/test_user_copy.c b/lib/test_user_copy.c
index e161f04..f051023 100644
--- a/lib/test_user_copy.c
+++ b/lib/test_user_copy.c
@@ -39,14 +39,135 @@
# define TEST_U64
#endif
-#define test(condition, msg) \
-({ \
- int cond = (condition); \
- if (cond) \
- pr_warn("%s\n", msg); \
- cond; \
+#define test(condition, msg, ...) \
+({ \
+ int cond = (condition); \
+ if (cond) \
+ pr_warn("[%d] " msg "\n", __LINE__, ##__VA_ARGS__); \
+ cond; \
})
+static bool is_zeroed(void *from, size_t size)
+{
+ return memchr_inv(from, 0x0, size) == NULL;
+}
+
+static int test_check_nonzero_user(char *kmem, char __user *umem, size_t size)
+{
+ int ret = 0;
+ size_t start, end, i;
+ size_t zero_start = size / 4;
+ size_t zero_end = size - zero_start;
+
+ /*
+ * We conduct a series of check_nonzero_user() tests on a block of memory
+ * with the following byte-pattern (trying every possible [start,end]
+ * pair):
+ *
+ * [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ]
+ *
+ * And we verify that check_nonzero_user() acts identically to memchr_inv().
+ */
+
+ memset(kmem, 0x0, size);
+ for (i = 1; i < zero_start; i += 2)
+ kmem[i] = 0xff;
+ for (i = zero_end; i < size; i += 2)
+ kmem[i] = 0xff;
+
+ ret |= test(copy_to_user(umem, kmem, size),
+ "legitimate copy_to_user failed");
+
+ for (start = 0; start <= size; start++) {
+ for (end = start; end <= size; end++) {
+ size_t len = end - start;
+ int retval = check_zeroed_user(umem + start, len);
+ int expected = is_zeroed(kmem + start, len);
+
+ ret |= test(retval != expected,
+ "check_nonzero_user(=%d) != memchr_inv(=%d) mismatch (start=%zu, end=%zu)",
+ retval, expected, start, end);
+ }
+ }
+
+ return ret;
+}
+
+static int test_copy_struct_from_user(char *kmem, char __user *umem,
+ size_t size)
+{
+ int ret = 0;
+ char *umem_src = NULL, *expected = NULL;
+ size_t ksize, usize;
+
+ umem_src = kmalloc(size, GFP_KERNEL);
+ ret = test(umem_src == NULL, "kmalloc failed");
+ if (ret)
+ goto out_free;
+
+ expected = kmalloc(size, GFP_KERNEL);
+ ret = test(expected == NULL, "kmalloc failed");
+ if (ret)
+ goto out_free;
+
+ /* Fill umem with a fixed byte pattern. */
+ memset(umem_src, 0x3e, size);
+ ret |= test(copy_to_user(umem, umem_src, size),
+ "legitimate copy_to_user failed");
+
+ /* Check basic case -- (usize == ksize). */
+ ksize = size;
+ usize = size;
+
+ memcpy(expected, umem_src, ksize);
+
+ memset(kmem, 0x0, size);
+ ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+ "copy_struct_from_user(usize == ksize) failed");
+ ret |= test(memcmp(kmem, expected, ksize),
+ "copy_struct_from_user(usize == ksize) gives unexpected copy");
+
+ /* Old userspace case -- (usize < ksize). */
+ ksize = size;
+ usize = size / 2;
+
+ memcpy(expected, umem_src, usize);
+ memset(expected + usize, 0x0, ksize - usize);
+
+ memset(kmem, 0x0, size);
+ ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+ "copy_struct_from_user(usize < ksize) failed");
+ ret |= test(memcmp(kmem, expected, ksize),
+ "copy_struct_from_user(usize < ksize) gives unexpected copy");
+
+ /* New userspace (-E2BIG) case -- (usize > ksize). */
+ ksize = size / 2;
+ usize = size;
+
+ memset(kmem, 0x0, size);
+ ret |= test(copy_struct_from_user(kmem, ksize, umem, usize) != -E2BIG,
+ "copy_struct_from_user(usize > ksize) didn't give E2BIG");
+
+ /* New userspace (success) case -- (usize > ksize). */
+ ksize = size / 2;
+ usize = size;
+
+ memcpy(expected, umem_src, ksize);
+ ret |= test(clear_user(umem + ksize, usize - ksize),
+ "legitimate clear_user failed");
+
+ memset(kmem, 0x0, size);
+ ret |= test(copy_struct_from_user(kmem, ksize, umem, usize),
+ "copy_struct_from_user(usize > ksize) failed");
+ ret |= test(memcmp(kmem, expected, ksize),
+ "copy_struct_from_user(usize > ksize) gives unexpected copy");
+
+out_free:
+ kfree(expected);
+ kfree(umem_src);
+ return ret;
+}
+
static int __init test_user_copy_init(void)
{
int ret = 0;
@@ -114,6 +235,11 @@
#endif
#undef test_legit
+ /* Test usage of check_nonzero_user(). */
+ ret |= test_check_nonzero_user(kmem, usermem, 2 * PAGE_SIZE);
+ /* Test usage of copy_struct_from_user(). */
+ ret |= test_copy_struct_from_user(kmem, usermem, 2 * PAGE_SIZE);
+
/*
* Invalid usage: none of these copies should succeed.
*/
diff --git a/lib/usercopy.c b/lib/usercopy.c
index 3744b2a..641c4e7 100644
--- a/lib/usercopy.c
+++ b/lib/usercopy.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/uaccess.h>
+#include <linux/bitops.h>
/* out-of-line parts */
@@ -31,3 +32,57 @@
}
EXPORT_SYMBOL(_copy_to_user);
#endif
+
+/**
+ * check_zeroed_user: check if a userspace buffer only contains zero bytes
+ * @from: Source address, in userspace.
+ * @size: Size of buffer.
+ *
+ * This is effectively shorthand for "memchr_inv(from, 0, size) == NULL" for
+ * userspace addresses (and is more efficient because we don't care where the
+ * first non-zero byte is).
+ *
+ * Returns:
+ * * 0: There were non-zero bytes present in the buffer.
+ * * 1: The buffer was full of zero bytes.
+ * * -EFAULT: access to userspace failed.
+ */
+int check_zeroed_user(const void __user *from, size_t size)
+{
+ unsigned long val;
+ uintptr_t align = (uintptr_t) from % sizeof(unsigned long);
+
+ if (unlikely(size == 0))
+ return 1;
+
+ from -= align;
+ size += align;
+
+ if (!user_access_begin(VERIFY_READ, from, size))
+ return -EFAULT;
+
+ unsafe_get_user(val, (unsigned long __user *) from, err_fault);
+ if (align)
+ val &= ~aligned_byte_mask(align);
+
+ while (size > sizeof(unsigned long)) {
+ if (unlikely(val))
+ goto done;
+
+ from += sizeof(unsigned long);
+ size -= sizeof(unsigned long);
+
+ unsafe_get_user(val, (unsigned long __user *) from, err_fault);
+ }
+
+ if (size < sizeof(unsigned long))
+ val &= aligned_byte_mask(size);
+
+done:
+ user_access_end();
+ return (val == 0);
+err_fault:
+ user_access_end();
+ return -EFAULT;
+}
+EXPORT_SYMBOL(check_zeroed_user);
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index dbdf75a..0909cfe 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -104,18 +104,12 @@
lockdep_assert_held(&rdev->bss_lock);
bss->refcount++;
- if (bss->pub.hidden_beacon_bss) {
- bss = container_of(bss->pub.hidden_beacon_bss,
- struct cfg80211_internal_bss,
- pub);
- bss->refcount++;
- }
- if (bss->pub.transmitted_bss) {
- bss = container_of(bss->pub.transmitted_bss,
- struct cfg80211_internal_bss,
- pub);
- bss->refcount++;
- }
+
+ if (bss->pub.hidden_beacon_bss)
+ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
+
+ if (bss->pub.transmitted_bss)
+ bss_from_pub(bss->pub.transmitted_bss)->refcount++;
}
static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
@@ -324,6 +318,14 @@
return 0;
}
+ /* This is a bit weird - it's not on the list, but already on another
+ * one! The only way that could happen is if there's some BSSID/SSID
+ * shared by multiple APs in their multi-BSSID profiles, potentially
+ * with hidden SSID mixed in ... ignore it.
+ */
+ if (!list_empty(&nontrans_bss->nontrans_list))
+ return -EINVAL;
+
/* add to the list */
list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
return 0;
@@ -1158,6 +1160,8 @@
new->refcount = 1;
INIT_LIST_HEAD(&new->hidden_list);
INIT_LIST_HEAD(&new->pub.nontrans_list);
+ /* we'll set this later if it was non-NULL */
+ new->pub.transmitted_bss = NULL;
if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
@@ -1382,9 +1386,14 @@
*/
if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
&res->pub)) {
- if (__cfg80211_unlink_bss(rdev, res))
+ if (__cfg80211_unlink_bss(rdev, res)) {
rdev->bss_generation++;
+ res = NULL;
+ }
}
+
+ if (!res)
+ return NULL;
}
trace_cfg80211_return_bss(&res->pub);
@@ -1540,7 +1549,7 @@
size_t new_ie_len;
struct cfg80211_bss_ies *new_ies;
const struct cfg80211_bss_ies *old;
- u8 cpy_len;
+ size_t cpy_len;
ie = mgmt->u.probe_resp.variable;