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(&timestamp, sizeof(timestamp),
+	if (copy_struct_from_user(&timestamp, 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;