Merge "Revert^2 "Switch the loader to a noexcept version of libc++"" into main
diff --git a/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h b/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
index 885e47f..ea63e36 100644
--- a/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
+++ b/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
@@ -44,9 +44,7 @@
 
 #elif defined(__riscv)
 
-// No `lga` in clang unless https://reviews.llvm.org/D107278 lands.
-// `la` is equivalent when using PIC (which we do) though.
-#define GOT_RELOC(sym) la a0, sym
+#define GOT_RELOC(sym) lga a0, sym
 #define CALL(sym) call sym@plt
 #define DATA_WORD(val) .quad val
 #define MAIN .globl main; main: li a0, 0; ret
diff --git a/benchmarks/util.h b/benchmarks/util.h
index 99eed5f..347dc35 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -71,7 +71,7 @@
 
 bool LockToCPU(int cpu_to_lock);
 
-static __inline __attribute__ ((__always_inline__)) void MakeAllocationResident(
+static inline __attribute__((__always_inline__)) void MakeAllocationResident(
     void* ptr, size_t nbytes, int pagesize) {
   uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
   for (size_t i = 0; i < nbytes; i += pagesize) {
diff --git a/docs/status.md b/docs/status.md
index 2919471..bc8ab6a 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -397,22 +397,25 @@
 overrun is detected, the program is safely aborted as in this
 [example](https://source.android.com/devices/tech/debug/native-crash#fortify).
 
-Note that in recent releases Android's FORTIFY has been extended to
-cover other issues. It can now detect, for example, passing `O_CREAT`
-to open(2) without specifying a mode. It also performs some checking
-regardless of whether the caller was built with FORTIFY enabled. In P,
-for example, calling a `pthread_mutex_` function on a destroyed mutex,
-calling a `<dirent.h>` function on a null pointer, using `%n` with the
-printf(3) family, or using the scanf(3) `m` modifier incorrectly will
-all result in FORTIFY failures even for code not built with FORTIFY.
+Note that Android's FORTIFY has been extended to cover other issues. It can
+detect, for example, passing `O_CREAT` to open(2) without specifying a mode. It
+also performs some checking regardless of whether the caller was built with
+FORTIFY enabled. From API level 28, for example, calling a `pthread_mutex_`
+function on a destroyed mutex, calling a `<dirent.h>` function on a null
+pointer, using `%n` with the printf(3) family, or using the scanf(3) `m`
+modifier incorrectly will all result in FORTIFY failures even for code not built
+with FORTIFY.
 
 More background information is available in our
 [FORTIFY in Android](https://android-developers.googleblog.com/2017/04/fortify-in-android.html)
-blog post.
+blog post, and there's more detail about the implementation in
+[The Anatomy of Clang FORTIFY](clang_fortify_anatomy.md).
 
-The Android platform is built with `-D_FORTIFY_SOURCE=2`, but NDK users
-need to manually enable FORTIFY by setting that themselves in whatever
-build system they're using. The exact subset of FORTIFY available to
+The Android platform is built with `-D_FORTIFY_SOURCE=2`. Users of ndk-build
+or the NDK's CMake toolchain file also get this by default with NDK r21 or
+newer. Users of other build systems
+need to manually enable FORTIFY by setting `_FORTIFY_SOURCE` themselves in
+whatever build system they're using. The exact subset of FORTIFY available to
 NDK users will depend on their target ABI level, because when a FORTIFY
 check can't be guaranteed at compile-time, a call to a run-time `_chk`
 function is added.
diff --git a/libc/Android.bp b/libc/Android.bp
index 84fa498..2efca68 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -55,7 +55,9 @@
 cc_defaults {
     name: "libc_defaults",
     defaults: ["linux_bionic_supported"],
-    cflags: libc_common_flags,
+    cflags: libc_common_flags + [
+        "-DUSE_SCUDO",
+    ],
     asflags: libc_common_flags,
     conlyflags: ["-std=gnu99"],
     cppflags: [],
@@ -98,8 +100,8 @@
         malloc_pattern_fill_contents: {
             cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"],
         },
-        malloc_not_svelte: {
-            cflags: ["-DUSE_SCUDO"],
+        malloc_low_memory: {
+            cflags: ["-UUSE_SCUDO"],
         },
     },
 
@@ -112,32 +114,31 @@
     tidy_disabled_srcs: ["upstream-*/**/*.c"],
 }
 
-libc_scudo_product_variables = {
-    malloc_not_svelte: {
-        cflags: ["-DUSE_SCUDO"],
-        whole_static_libs: ["libscudo"],
-        exclude_static_libs: [
-            "libjemalloc5",
-            "libc_jemalloc_wrapper",
-        ],
-    },
-}
-
 // Defaults for native allocator libs/includes to make it
 // easier to change.
-// To disable scudo for the non-svelte config remove the line:
-//     product_variables: libc_scudo_product_variables,
-// in the cc_defaults below.
 // ========================================================
 cc_defaults {
     name: "libc_native_allocator_defaults",
 
     whole_static_libs: [
-        "libjemalloc5",
-        "libc_jemalloc_wrapper",
+        "libscudo",
+    ],
+    cflags: [
+        "-DUSE_SCUDO",
     ],
     header_libs: ["gwp_asan_headers"],
-    product_variables: libc_scudo_product_variables,
+    product_variables: {
+        malloc_low_memory: {
+            cflags: ["-UUSE_SCUDO"],
+            whole_static_libs: [
+                "libjemalloc5",
+                "libc_jemalloc_wrapper",
+            ],
+            exclude_static_libs: [
+                "libscudo",
+            ],
+        },
+    },
 }
 
 // Functions not implemented by jemalloc directly, or that need to
@@ -2990,3 +2991,8 @@
     name: "versioner-dependencies",
     srcs: ["versioner-dependencies/**/*"],
 }
+
+filegroup {
+    name: "linux_capability_header",
+    srcs: ["kernel/uapi/linux/capability.h"],
+}
diff --git a/libc/arch-arm64/bionic/__bionic_clone.S b/libc/arch-arm64/bionic/__bionic_clone.S
index e9932ad..581b47a 100644
--- a/libc/arch-arm64/bionic/__bionic_clone.S
+++ b/libc/arch-arm64/bionic/__bionic_clone.S
@@ -39,7 +39,7 @@
     svc     #0
 
     # Are we the child?
-    cbz     x0, .L_bc_child
+    cbz     x0, L(child)
 
     # Set errno if something went wrong.
     cmn     x0, #(MAX_ERRNO + 1)
@@ -48,7 +48,7 @@
 
     ret
 
-.L_bc_child:
+L(child):
     # We're in the child now. Set the end of the frame record chain.
     mov     x29, #0
     # Setting x30 to 0 will make the unwinder stop at __start_thread.
diff --git a/libc/arch-arm64/bionic/vfork.S b/libc/arch-arm64/bionic/vfork.S
index dd16349..26ac255 100644
--- a/libc/arch-arm64/bionic/vfork.S
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -72,7 +72,7 @@
     mov     x8, __NR_clone
     svc     #0
 
-    cbz     x0, .L_exit
+    cbz     x0, L(done)
 
     // rc != 0: reset cached_pid_ and vforked_.
     str     w10, [x9, #20]
@@ -80,7 +80,7 @@
     cneg    x0, x0, hi
     b.hi    __set_errno_internal
 
-.L_exit:
+L(done):
     ret
 END(vfork)
 
diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp
index db002b8..a42c361 100644
--- a/libc/arch-arm64/dynamic_function_dispatch.cpp
+++ b/libc/arch-arm64/dynamic_function_dispatch.cpp
@@ -30,18 +30,22 @@
 #include <stddef.h>
 #include <sys/auxv.h>
 
-#define MIDR_IMPL_ID_SHIFT 24u
-#define MIDR_IMPL_ID_MASK 0xFF
-#define CPU_VARIANT_SHIFT 20u
-#define CPU_VARIANT_MASK 0xF
+static inline bool __bionic_is_oryon(unsigned long hwcap) {
+    if (!(hwcap & HWCAP_CPUID)) return false;
 
-/* Macro to identify CPU implementer */
-#define QCOM_IMPL_ID 0x51
+    // Extract the implementor and variant bits from MIDR_EL1.
+    // https://www.kernel.org/doc/html/latest/arch/arm64/cpu-feature-registers.html#list-of-registers-with-visible-features
+    unsigned long midr;
+    __asm__ __volatile__("mrs %0, MIDR_EL1" : "=r"(midr));
+    uint16_t cpu = (midr >> 20) & 0xfff;
 
-/* Macro to indentify qualcomm CPU variants which supports
- * __memcpy_aarch64_nt routine
- */
-#define QCOM_ORYON_CPU_VARIANTS 0x5
+    auto make_cpu = [](unsigned implementor, unsigned variant) {
+        return (implementor << 4) | variant;
+    };
+
+    // Check for implementor Qualcomm's variants 0x1..0x5 (Oryon).
+    return cpu >= make_cpu('Q', 0x1) && cpu <= make_cpu('Q', 0x5);
+}
 
 extern "C" {
 
@@ -62,68 +66,20 @@
 
 typedef void* memcpy_func(void*, const void*, size_t);
 DEFINE_IFUNC_FOR(memcpy) {
-  unsigned long midr;
-  unsigned int impl_id, cpu_variant;
-
-  /* Check if hardware capability CPUID is available */
-  if (arg->_hwcap & HWCAP_CPUID) {
-    /* Read the MIDR register */
-    asm("mrs %0, MIDR_EL1 \n\t" : "=r"(midr));
-
-    /* Extract the CPU Implementer ID */
-    impl_id = (midr >> MIDR_IMPL_ID_SHIFT) & (MIDR_IMPL_ID_MASK);
-
-    /* Check for Qualcomm implementer ID */
-    if (impl_id == QCOM_IMPL_ID) {
-      cpu_variant = (midr >> CPU_VARIANT_SHIFT) & CPU_VARIANT_MASK;
-
-      /* Check for Qualcomm Oryon CPU variants: 0x1, 0x2, 0x3, 0x4, 0x5 */
-      if (cpu_variant <= QCOM_ORYON_CPU_VARIANTS) {
+    if (__bionic_is_oryon(arg->_hwcap)) {
         RETURN_FUNC(memcpy_func, __memcpy_aarch64_nt);
-      } else {
+    } else if (arg->_hwcap & HWCAP_ASIMD) {
+        RETURN_FUNC(memcpy_func, __memcpy_aarch64_simd);
+    } else {
         RETURN_FUNC(memcpy_func, __memcpy_aarch64);
-      }
     }
-  }
-  /* If CPU implementer is not Qualcomm, choose the custom
-   * implementation based on CPU architecture feature
-   * */
-  if (arg->_hwcap & HWCAP_ASIMD) {
-    RETURN_FUNC(memcpy_func, __memcpy_aarch64_simd);
-  } else {
-    RETURN_FUNC(memcpy_func, __memcpy_aarch64);
-  }
 }
 
 typedef void* memmove_func(void*, const void*, size_t);
 DEFINE_IFUNC_FOR(memmove) {
-  unsigned long midr;
-  unsigned int impl_id, cpu_variant;
-
-  /* Check if hardware capability CPUID is available */
-  if (arg->_hwcap & HWCAP_CPUID) {
-    /* Read the MIDR register */
-    asm("mrs %0, MIDR_EL1 \n\t" : "=r"(midr));
-
-    /* Extract the CPU Implementer ID */
-    impl_id = (midr >> MIDR_IMPL_ID_SHIFT) & (MIDR_IMPL_ID_MASK);
-
-    /* Check for Qualcomm implementer ID */
-    if (impl_id == QCOM_IMPL_ID) {
-      cpu_variant = (midr >> CPU_VARIANT_SHIFT) & CPU_VARIANT_MASK;
-
-      /* Check for Qualcomm Oryon CPU variants: 0x1, 0x2, 0x3, 0x4, 0x5 */
-      if (cpu_variant <= QCOM_ORYON_CPU_VARIANTS) {
-        RETURN_FUNC(memcpy_func, __memmove_aarch64_nt);
-      } else {
-        RETURN_FUNC(memcpy_func, __memmove_aarch64);
-      }
-    }
-  }
-  /* If CPU implementer is not Qualcomm, choose the custom
-   * implementation based on CPU architecture feature
-   * */
-  if (arg->_hwcap & HWCAP_ASIMD) {
+  if (__bionic_is_oryon(arg->_hwcap)) {
+    RETURN_FUNC(memcpy_func, __memmove_aarch64_nt);
+  } else if (arg->_hwcap & HWCAP_ASIMD) {
     RETURN_FUNC(memmove_func, __memmove_aarch64_simd);
   } else {
     RETURN_FUNC(memmove_func, __memmove_aarch64);
@@ -137,32 +93,11 @@
 
 typedef int memset_func(void*, int, size_t);
 DEFINE_IFUNC_FOR(memset) {
-  unsigned long midr;
-  unsigned int impl_id, cpu_variant;
-
-  if (arg->_hwcap & HWCAP_CPUID) {
-    /* Read the MIDR register */
-    asm("mrs %0, MIDR_EL1 \n\t" : "=r"(midr));
-
-    /* Extract the CPU Implementer ID */
-    impl_id = (midr >> MIDR_IMPL_ID_SHIFT) & (MIDR_IMPL_ID_MASK);
-
-    /* Check for Qualcomm implementer ID */
-    if (impl_id == QCOM_IMPL_ID) {
-      cpu_variant = (midr >> CPU_VARIANT_SHIFT) & CPU_VARIANT_MASK;
-
-      /* Check for Qualcomm Oryon CPU variants: 0x1, 0x2, 0x3, 0x4, 0x5 */
-      if (cpu_variant <= QCOM_ORYON_CPU_VARIANTS) {
+    if (__bionic_is_oryon(arg->_hwcap)) {
         RETURN_FUNC(memset_func, __memset_aarch64_nt);
-      } else {
-        RETURN_FUNC(memset_func, __memset_aarch64);
-      }
     } else {
-      RETURN_FUNC(memset_func, __memset_aarch64);
+        RETURN_FUNC(memset_func, __memset_aarch64);
     }
-  } else {
-    RETURN_FUNC(memset_func, __memset_aarch64);
-  }
 }
 
 typedef char* stpcpy_func(char*, const char*, size_t);
diff --git a/libc/arch-arm64/string/__memcpy_chk.S b/libc/arch-arm64/string/__memcpy_chk.S
index a8e9e83..c9fc2f7 100644
--- a/libc/arch-arm64/string/__memcpy_chk.S
+++ b/libc/arch-arm64/string/__memcpy_chk.S
@@ -31,10 +31,10 @@
 ENTRY(__memcpy_chk)
   cmp x2, x3
   // Direct b.ls memcpy may not have enough range
-  b.hi .L_memcpy_chk_fail
+  b.hi L(__memcpy_chk_fail_trampoline)
   b memcpy
 
-.L_memcpy_chk_fail:
+L(__memcpy_chk_fail_trampoline):
   // Preserve for accurate backtrace.
   stp x29, x30, [sp, -16]!
   .cfi_def_cfa_offset 16
diff --git a/libc/arch-arm64/string/__memset_chk.S b/libc/arch-arm64/string/__memset_chk.S
index e1e29d0..7a105ce 100644
--- a/libc/arch-arm64/string/__memset_chk.S
+++ b/libc/arch-arm64/string/__memset_chk.S
@@ -31,10 +31,10 @@
 ENTRY(__memset_chk)
   cmp x2, x3
   // Direct b.ls memcpy may not have enough range
-  b.hi .L_memset_chk_fail
+  b.hi L(__memset_chk_fail_trampoline)
   b memset
 
-.L_memset_chk_fail:
+L(__memset_chk_fail_trampoline):
   // Preserve for accurate backtrace.
   stp x29, x30, [sp, -16]!
   .cfi_def_cfa_offset 16
diff --git a/libc/arch-riscv64/bionic/__bionic_clone.S b/libc/arch-riscv64/bionic/__bionic_clone.S
index 2827857..be386b1 100644
--- a/libc/arch-riscv64/bionic/__bionic_clone.S
+++ b/libc/arch-riscv64/bionic/__bionic_clone.S
@@ -41,19 +41,19 @@
   ecall
 
   # Are we the child?
-  beqz a0, .L_bc_child
+  beqz a0, L(child)
 
   # Did the clone(2) fail?
-  bltz a0, .L_bc_failure
+  bltz a0, L(failure)
   # Nope, we're the parent, and our work here is done.
   ret
 
-.L_bc_failure:
+L(failure):
   # Set errno if something went wrong.
   neg a0, a0
   tail __set_errno_internal
 
-.L_bc_child:
+L(child):
   # We're in the child now. Set the end of the frame record chain.
   li fp, 0
   # Setting ra to 0 will make the unwinder stop at __start_thread.
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index 81b1e35..5de1099 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -205,7 +205,7 @@
   // Check the checksum before doing anything.
   m_calculate_checksum t0, a0, t1
   ld t1, _JB_CHECKSUM(a0)
-  bne t0, t1, 3f
+  bne t0, t1, L(checksum_failure)
 
   // Do we need to restore the signal mask?
   ld a2, _JB_SIGFLAG(a0)
@@ -290,7 +290,7 @@
   mv a0, a1
   ret
 
-3:
+L(checksum_failure):
   call __bionic_setjmp_checksum_mismatch
 END(siglongjmp)
 
diff --git a/libc/arch-riscv64/bionic/syscall.S b/libc/arch-riscv64/bionic/syscall.S
index 1a6e60a..ca735c7 100644
--- a/libc/arch-riscv64/bionic/syscall.S
+++ b/libc/arch-riscv64/bionic/syscall.S
@@ -44,10 +44,10 @@
 
   // Did it fail?
   li a7, -MAX_ERRNO
-  bgtu a0, a7, 1f
-
+  bgtu a0, a7, L(failure)
   ret
-1:
+
+L(failure):
   neg a0, a0
   tail __set_errno_internal
 END(syscall)
diff --git a/libc/arch-riscv64/bionic/vfork.S b/libc/arch-riscv64/bionic/vfork.S
index 29ab405..06ebc3e 100644
--- a/libc/arch-riscv64/bionic/vfork.S
+++ b/libc/arch-riscv64/bionic/vfork.S
@@ -51,16 +51,16 @@
   ecall
 
   // if (rc == 0) we're the child, and finished...
-  beqz    a0, .L_success
+  beqz    a0, L(success)
 
   // else if (rc != 0): reset cached_pid_ and vforked_...
   sw      t2, 20(t0)
   // ...and work out whether we succeeded or failed.
-  bltz    a0, .L_failure
-.L_success:
+  bltz    a0, L(failure)
+L(success):
   ret
 
-.L_failure:
+L(failure):
   neg     a0, a0
   tail    __set_errno_internal
 END(vfork)
diff --git a/libc/arch-riscv64/dynamic_function_dispatch.cpp b/libc/arch-riscv64/dynamic_function_dispatch.cpp
index 265ce3e..bb2ba51 100644
--- a/libc/arch-riscv64/dynamic_function_dispatch.cpp
+++ b/libc/arch-riscv64/dynamic_function_dispatch.cpp
@@ -35,7 +35,7 @@
 
 extern "C" {
 
-static __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
+static inline __always_inline int ifunc_faccessat(int dir_fd, const char* path, int mode) {
   register long a0 __asm__("a0") = dir_fd;
   register long a1 __asm__("a1") = reinterpret_cast<long>(path);
   register long a2 __asm__("a2") = mode;
diff --git a/libc/arch-x86/bionic/setjmp.S b/libc/arch-x86/bionic/setjmp.S
index d22683a..b9e6bdf 100644
--- a/libc/arch-x86/bionic/setjmp.S
+++ b/libc/arch-x86/bionic/setjmp.S
@@ -65,19 +65,16 @@
 .endm
 
 ENTRY_WEAK_FOR_NATIVE_BRIDGE(setjmp)
-  movl 4(%esp),%ecx
   mov $1,%eax
   jmp .L_sigsetjmp
 END(setjmp)
 
 ENTRY_WEAK_FOR_NATIVE_BRIDGE(_setjmp)
-  movl 4(%esp),%ecx
   movl $0,%eax
   jmp .L_sigsetjmp
 END(_setjmp)
 
 ENTRY_WEAK_FOR_NATIVE_BRIDGE(sigsetjmp)
-  movl 4(%esp),%ecx
   movl 8(%esp),%eax
 
 .L_sigsetjmp:
@@ -88,6 +85,7 @@
   PIC_EPILOGUE
 
   // Record the setjmp cookie and whether or not we're saving the signal mask.
+  movl 4(%esp),%ecx
   movl %eax,(_JB_SIGFLAG * 4)(%ecx)
 
   // Do we need to save the signal mask?
diff --git a/libc/bionic/execinfo.cpp b/libc/bionic/execinfo.cpp
index d129f7c..e53a037 100644
--- a/libc/bionic/execinfo.cpp
+++ b/libc/bionic/execinfo.cpp
@@ -73,6 +73,11 @@
 #elif defined(__aarch64__)
     // All instructions are 4 bytes long, skip back one instruction.
     ip -= 4;
+#elif defined(__riscv)
+    // C instructions are the shortest at 2 bytes long. (Unlike thumb, it's
+    // non-trivial to recognize C instructions when going backwards in the
+    // instruction stream.)
+    ip -= 2;
 #elif defined(__i386__) || defined(__x86_64__)
     // It's difficult to decode exactly where the previous instruction is,
     // so subtract 1 to estimate where the instruction lives.
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 7dee5e3..80f7c20 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -99,8 +99,8 @@
 }
 
 size_t __fread_chk(void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
-  size_t total;
-  if (__predict_false(__size_mul_overflow(size, count, &total))) {
+  unsigned long total;
+  if (__predict_false(__builtin_umull_overflow(size, count, &total))) {
     // overflow: trigger the error path in fread
     return fread(buf, size, count, stream);
   }
@@ -109,8 +109,8 @@
 }
 
 size_t __fwrite_chk(const void* buf, size_t size, size_t count, FILE* stream, size_t buf_size) {
-  size_t total;
-  if (__predict_false(__size_mul_overflow(size, count, &total))) {
+  unsigned long total;
+  if (__predict_false(__builtin_umull_overflow(size, count, &total))) {
     // overflow: trigger the error path in fwrite
     return fwrite(buf, size, count, stream);
   }
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 251633d..2124f51 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -57,7 +57,7 @@
 static gwp_asan::GuardedPoolAllocator GuardedAlloc;
 static const MallocDispatch* prev_dispatch;
 
-using Action = android_mallopt_gwp_asan_options_t::Action;
+using Mode = android_mallopt_gwp_asan_options_t::Mode;
 using Options = gwp_asan::options::Options;
 
 // basename() is a mess, see the manpage. Let's be explicit what handling we
@@ -258,14 +258,14 @@
   options->Backtrace = android_unsafe_frame_pointer_chase;
   options->SampleRate = kDefaultSampleRate;
   options->MaxSimultaneousAllocations = kDefaultMaxAllocs;
+  options->Recoverable = true;
+  GwpAsanRecoverable = true;
 
-  *process_sample_rate = 1;
-  if (mallopt_options.desire == Action::TURN_ON_WITH_SAMPLING) {
+  if (mallopt_options.mode == Mode::SYSTEM_PROCESS_OR_SYSTEM_APP ||
+      mallopt_options.mode == Mode::APP_MANIFEST_DEFAULT) {
     *process_sample_rate = kDefaultProcessSampling;
-  } else if (mallopt_options.desire == Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING) {
-    *process_sample_rate = kDefaultProcessSampling;
-    options->Recoverable = true;
-    GwpAsanRecoverable = true;
+  } else {
+    *process_sample_rate = 1;
   }
 }
 
@@ -285,7 +285,7 @@
   // be used. Tests still continue to use the environment variable though.
   if (*basename != '\0') {
     const char* default_sysprop = system_sysprop;
-    if (mallopt_options.desire == Action::TURN_ON_FOR_APP) {
+    if (mallopt_options.mode == Mode::APP_MANIFEST_ALWAYS) {
       default_sysprop = app_sysprop;
     }
     async_safe_format_buffer(&program_specific_sysprop[0], kSyspropMaxLen, "%s%s",
@@ -403,7 +403,7 @@
         /* default */ kDefaultMaxAllocs / frequency_multiplier;
   }
 
-  bool recoverable = false;
+  bool recoverable = true;
   if (GetGwpAsanBoolOption(&recoverable, mallopt_options, kRecoverableSystemSysprop,
                            kRecoverableAppSysprop, kRecoverableTargetedSyspropPrefix,
                            kRecoverableEnvVar, "recoverable")) {
@@ -425,7 +425,7 @@
   Options options;
   unsigned process_sample_rate = kDefaultProcessSampling;
   if (!GetGwpAsanOptions(&options, &process_sample_rate, mallopt_options) &&
-      mallopt_options.desire == Action::DONT_TURN_ON_UNLESS_OVERRIDDEN) {
+      mallopt_options.mode == Mode::APP_MANIFEST_NEVER) {
     return false;
   }
 
@@ -492,7 +492,7 @@
 
   android_mallopt_gwp_asan_options_t mallopt_options;
   mallopt_options.program_name = progname;
-  mallopt_options.desire = Action::TURN_ON_WITH_SAMPLING;
+  mallopt_options.mode = Mode::SYSTEM_PROCESS_OR_SYSTEM_APP;
 
   return MaybeInitGwpAsan(globals, mallopt_options);
 }
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index c4347e8..c8a025f 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -38,6 +38,11 @@
 extern "C" void scudo_malloc_disable_memory_tagging();
 extern "C" void scudo_malloc_set_track_allocation_stacks(int);
 
+extern "C" const char* __scudo_get_stack_depot_addr();
+extern "C" const char* __scudo_get_ring_buffer_addr();
+extern "C" size_t __scudo_get_ring_buffer_size();
+extern "C" size_t __scudo_get_stack_depot_size();
+
 // Protected by `g_heap_tagging_lock`.
 static HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
 
@@ -65,7 +70,7 @@
     };
   });
 
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
   switch (heap_tagging_level) {
     case M_HEAP_TAGGING_LEVEL_TBI:
     case M_HEAP_TAGGING_LEVEL_NONE:
@@ -123,7 +128,7 @@
           return false;
         }
       }
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
       scudo_malloc_disable_memory_tagging();
 #endif
       break;
@@ -151,13 +156,17 @@
         if (!set_tcf_on_all_threads(PR_MTE_TCF_ASYNC | PR_MTE_TCF_SYNC)) {
           set_tcf_on_all_threads(PR_MTE_TCF_ASYNC);
         }
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
         scudo_malloc_set_track_allocation_stacks(0);
 #endif
       } else if (tag_level == M_HEAP_TAGGING_LEVEL_SYNC) {
         set_tcf_on_all_threads(PR_MTE_TCF_SYNC);
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
         scudo_malloc_set_track_allocation_stacks(1);
+        __libc_shared_globals()->scudo_ring_buffer = __scudo_get_ring_buffer_addr();
+        __libc_shared_globals()->scudo_ring_buffer_size = __scudo_get_ring_buffer_size();
+        __libc_shared_globals()->scudo_stack_depot = __scudo_get_stack_depot_addr();
+        __libc_shared_globals()->scudo_stack_depot_size = __scudo_get_stack_depot_size();
 #endif
       }
       break;
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index a2bb1db..1bbdb29 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -77,9 +77,13 @@
 int je_mallopt(int param, int value) {
   // The only parameter we currently understand is M_DECAY_TIME.
   if (param == M_DECAY_TIME) {
-    // Only support setting the value to 1 or 0.
+    // Only support setting the value to -1 or 0 or 1.
     ssize_t decay_time_ms;
-    if (value) {
+    if (value < 0) {
+      // Given that SSIZE_MAX may not be supported in jemalloc, set this to a
+      // sufficiently large number that essentially disables the decay timer.
+      decay_time_ms = 10000000;
+    } else if (value) {
       decay_time_ms = 1000;
     } else {
       decay_time_ms = 0;
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index 944098f..c82c52e 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -96,7 +96,7 @@
   SetDefaultHeapTaggingLevel();
 
 // TODO(b/158870657) make this unconditional when all devices support SCUDO.
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
 #if defined(SCUDO_PATTERN_FILL_CONTENTS)
   scudo_malloc_set_pattern_fill_contents(1);
 #elif defined(SCUDO_ZERO_CONTENTS)
@@ -182,7 +182,7 @@
 extern "C" void scudo_malloc_set_add_large_allocation_slack(int add_slack);
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE void __libc_set_target_sdk_version(int target __unused) {
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
   scudo_malloc_set_add_large_allocation_slack(target < __ANDROID_API_S__);
 #endif
 }
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 1180a51..2dde2f1 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -61,7 +61,7 @@
 };
 
 void memtag_stack_dlopen_callback() {
-  async_safe_format_log(ANDROID_LOG_INFO, "libc", "remapping stacks as PROT_MTE");
+  async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "remapping stacks as PROT_MTE");
   __pthread_internal_remap_stack_with_mte();
 }
 
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index d86df30..3da0a92 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -297,6 +297,30 @@
   return level;
 }
 
+static int64_t __get_memtag_upgrade_secs() {
+  char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
+  if (!env) return 0;
+  int64_t timed_upgrade = 0;
+  static const char kAppProcessName[] = "app_process64";
+  const char* progname = __libc_shared_globals()->init_progname;
+  progname = progname ? __gnu_basename(progname) : nullptr;
+  // disable timed upgrade for zygote, as the thread spawned will violate the requirement
+  // that it be single-threaded.
+  if (!progname || strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) != 0) {
+    char* endptr;
+    timed_upgrade = strtoll(env, &endptr, 10);
+    if (*endptr != '\0' || timed_upgrade < 0) {
+      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                            "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s", env);
+      timed_upgrade = 0;
+    }
+  }
+  // Make sure that this does not get passed to potential processes inheriting
+  // this environment.
+  unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
+  return timed_upgrade;
+}
+
 // Figure out the desired memory tagging mode (sync/async, heap/globals/stack) for this executable.
 // This function is called from the linker before the main executable is relocated.
 __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte(
@@ -313,31 +337,7 @@
     }
     memtag_stack = true;
   }
-  char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS");
-  static const char kAppProcessName[] = "app_process64";
-  const char* progname = __libc_shared_globals()->init_progname;
-  progname = progname ? __gnu_basename(progname) : nullptr;
-  if (progname &&
-      strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) == 0) {
-    // disable timed upgrade for zygote, as the thread spawned will violate the requirement
-    // that it be single-threaded.
-    env = nullptr;
-  }
-  int64_t timed_upgrade = 0;
-  if (env) {
-    char* endptr;
-    timed_upgrade = strtoll(env, &endptr, 10);
-    if (*endptr != '\0' || timed_upgrade < 0) {
-      async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                            "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s",
-                            env);
-      timed_upgrade = 0;
-    }
-    // Make sure that this does not get passed to potential processes inheriting
-    // this environment.
-    unsetenv("BIONIC_MEMTAG_UPGRADE_SECS");
-  }
-  if (timed_upgrade) {
+  if (int64_t timed_upgrade = __get_memtag_upgrade_secs()) {
     if (level == M_HEAP_TAGGING_LEVEL_ASYNC) {
       async_safe_format_log(ANDROID_LOG_INFO, "libc",
                             "Attempting timed MTE upgrade from async to sync.");
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 9932e3e..596a1fc 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -123,7 +123,7 @@
   // Track the M_DECAY_TIME mallopt calls.
   if (param == M_DECAY_TIME && retval == 1) {
     __libc_globals.mutate([value](libc_globals* globals) {
-      if (value == 0) {
+      if (value <= 0) {
         atomic_store(&globals->decay_time_enabled, false);
       } else {
         atomic_store(&globals->decay_time_enabled, true);
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index 8858178..6db6251 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -381,7 +381,7 @@
 
   MaybeInitGwpAsanFromLibc(globals);
 
-#if defined(USE_SCUDO)
+#if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer)
   __libc_shared_globals()->scudo_stack_depot = __scudo_get_stack_depot_addr();
   __libc_shared_globals()->scudo_region_info = __scudo_get_region_info_addr();
   __libc_shared_globals()->scudo_ring_buffer = __scudo_get_ring_buffer_addr();
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index f522516..ccbbfcf 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -34,6 +34,8 @@
 #include <string.h>
 #include <time.h>
 
+#include "private/bionic_lock.h"
+
 // System calls.
 extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
 extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
@@ -60,6 +62,7 @@
   int sigev_notify;
 
   // The fields below are only needed for a SIGEV_THREAD timer.
+  Lock startup_handshake_lock;
   pthread_t callback_thread;
   void (*callback)(sigval_t);
   sigval_t callback_argument;
@@ -73,6 +76,18 @@
 static void* __timer_thread_start(void* arg) {
   PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg);
 
+  // Check that our parent managed to create the kernel timer and bail if not...
+  timer->startup_handshake_lock.lock();
+  if (timer->kernel_timer_id == -1) {
+    free(timer);
+    return nullptr;
+  }
+
+  // Give ourselves a specific meaningful name now we have a kernel timer.
+  char name[16]; // 16 is the kernel-imposed limit.
+  snprintf(name, sizeof(name), "POSIX timer %d", to_kernel_timer_id(timer));
+  pthread_setname_np(timer->callback_thread, name);
+
   sigset64_t sigset = {};
   sigaddset64(&sigset, TIMER_SIGNAL);
 
@@ -109,6 +124,7 @@
     return -1;
   }
 
+  timer->kernel_timer_id = -1;
   timer->sigev_notify = (evp == nullptr) ? SIGEV_SIGNAL : evp->sigev_notify;
 
   // If not a SIGEV_THREAD timer, the kernel can handle it without our help.
@@ -149,6 +165,10 @@
   sigaddset64(&sigset, TIMER_SIGNAL);
   sigset64_t old_sigset;
 
+  // Prevent the child thread from running until the timer has been created.
+  timer->startup_handshake_lock.init(false);
+  timer->startup_handshake_lock.lock();
+
   // Use __rt_sigprocmask instead of sigprocmask64 to avoid filtering out TIMER_SIGNAL.
   __rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
 
@@ -162,21 +182,21 @@
     return -1;
   }
 
+  // Try to create the kernel timer.
   sigevent se = *evp;
   se.sigev_signo = TIMER_SIGNAL;
   se.sigev_notify = SIGEV_THREAD_ID;
   se.sigev_notify_thread_id = pthread_gettid_np(timer->callback_thread);
-  if (__timer_create(clock_id, &se, &timer->kernel_timer_id) == -1) {
-    __timer_thread_stop(timer);
+  rc = __timer_create(clock_id, &se, &timer->kernel_timer_id);
+
+  // Let the child run (whether we created the kernel timer or not).
+  timer->startup_handshake_lock.unlock();
+  // If __timer_create(2) failed, the child will kill itself and free the
+  // timer struct, so we just need to exit.
+  if (rc == -1) {
     return -1;
   }
 
-  // Give the thread a specific meaningful name.
-  // It can't do this itself because the kernel timer isn't created until after it's running.
-  char name[16]; // 16 is the kernel-imposed limit.
-  snprintf(name, sizeof(name), "POSIX timer %d", to_kernel_timer_id(timer));
-  pthread_setname_np(timer->callback_thread, name);
-
   *timer_id = timer;
   return 0;
 }
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 091f711..c2abdea 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -240,7 +240,7 @@
 // On LP64, we could use more but there's no obvious advantage to doing
 // so, and the various media processes use RLIMIT_AS as a way to limit
 // the amount of allocation they'll do.
-#define PTHREAD_GUARD_SIZE max_page_size()
+#define PTHREAD_GUARD_SIZE max_android_page_size()
 
 // SIGSTKSZ (8KiB) is not big enough.
 // An snprintf to a stack buffer of size PATH_MAX consumes ~7KiB of stack.
diff --git a/libc/bionic/pthread_rwlock.cpp b/libc/bionic/pthread_rwlock.cpp
index ebf6697..6f3c6fe 100644
--- a/libc/bionic/pthread_rwlock.cpp
+++ b/libc/bionic/pthread_rwlock.cpp
@@ -69,11 +69,12 @@
 #define RWLOCKATTR_KIND_MASK     2
 #define RWLOCKATTR_RESERVED_MASK (~3)
 
-static inline __always_inline __always_inline bool __rwlockattr_getpshared(const pthread_rwlockattr_t* attr) {
+static inline __always_inline bool __rwlockattr_getpshared(const pthread_rwlockattr_t* attr) {
   return (*attr & RWLOCKATTR_PSHARED_MASK) >> RWLOCKATTR_PSHARED_SHIFT;
 }
 
-static inline __always_inline __always_inline void __rwlockattr_setpshared(pthread_rwlockattr_t* attr, int pshared) {
+static inline __always_inline void __rwlockattr_setpshared(pthread_rwlockattr_t* attr,
+                                                           int pshared) {
   *attr = (*attr & ~RWLOCKATTR_PSHARED_MASK) | (pshared << RWLOCKATTR_PSHARED_SHIFT);
 }
 
diff --git a/libc/bionic/sys_statvfs.cpp b/libc/bionic/sys_statvfs.cpp
index b3a0aca..3a05c3f 100644
--- a/libc/bionic/sys_statvfs.cpp
+++ b/libc/bionic/sys_statvfs.cpp
@@ -17,7 +17,7 @@
 #include <sys/statfs.h>
 #include <sys/statvfs.h>
 
-static __inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) {
+static inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) {
   dst->f_bsize = src->f_bsize;
   dst->f_frsize = src->f_frsize;
   dst->f_blocks = src->f_blocks;
diff --git a/libc/bionic/sys_thread_properties.cpp b/libc/bionic/sys_thread_properties.cpp
index d1a73b7..d7188f5 100644
--- a/libc/bionic/sys_thread_properties.cpp
+++ b/libc/bionic/sys_thread_properties.cpp
@@ -77,35 +77,9 @@
 
   // Find the thread-pointer register for the given thread.
   void** tp_reg = nullptr;
-#if defined(__x86_64__)
-  {
-    ErrnoRestorer errno_restorer;
-    errno = 0;
-    uintptr_t fs_base = ptrace(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr);
-    if (errno == 0) {
-      tp_reg = reinterpret_cast<void**>(fs_base);
-    }
-  }
-#elif defined(__i386__)
-  struct user_regs_struct regs;
-  struct iovec pt_iov = {
-      .iov_base = &regs,
-      .iov_len = sizeof(regs),
-  };
-
-  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
-    struct user_desc u_info;
-    u_info.entry_number = regs.xgs >> 3;
-    if (ptrace(PTRACE_GET_THREAD_AREA, tid, u_info.entry_number, &u_info) == 0) {
-      tp_reg = reinterpret_cast<void**>(u_info.base_addr);
-    }
-  }
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
   uint64_t reg;
-  struct iovec pt_iov {
-    .iov_base = &reg, .iov_len = sizeof(reg),
-  };
-
+  struct iovec pt_iov { .iov_base = &reg, .iov_len = sizeof(reg) };
   if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TLS, &pt_iov) == 0) {
     tp_reg = reinterpret_cast<void**>(reg);
   }
@@ -114,6 +88,31 @@
     // Reset the tp_reg if ptrace was unsuccessful.
     tp_reg = nullptr;
   }
+#elif defined(__i386__)
+  struct user_regs_struct regs;
+  struct iovec pt_iov = { .iov_base = &regs, .iov_len = sizeof(regs) };
+  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
+    struct user_desc u_info;
+    u_info.entry_number = regs.xgs >> 3;
+    if (ptrace(PTRACE_GET_THREAD_AREA, tid, u_info.entry_number, &u_info) == 0) {
+      tp_reg = reinterpret_cast<void**>(u_info.base_addr);
+    }
+  }
+#elif defined(__riscv)
+  struct user_regs_struct regs;
+  struct iovec pt_iov = { .iov_base = &regs, .iov_len = sizeof(regs) };
+  if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
+    tp_reg = reinterpret_cast<void**>(regs.tp);
+  }
+#elif defined(__x86_64__)
+  {
+    ErrnoRestorer errno_restorer;
+    errno = 0;
+    uintptr_t fs_base = ptrace(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr);
+    if (errno == 0) {
+      tp_reg = reinterpret_cast<void**>(fs_base);
+    }
+  }
 #endif
 
   if (tp_reg == nullptr) {
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index 6e49bce..73cf151 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -257,6 +257,21 @@
   }
 }
 
+static const char* __prop_error_to_string(int error) {
+  switch (error) {
+  case PROP_ERROR_READ_CMD: return "PROP_ERROR_READ_CMD";
+  case PROP_ERROR_READ_DATA: return "PROP_ERROR_READ_DATA";
+  case PROP_ERROR_READ_ONLY_PROPERTY: return "PROP_ERROR_READ_ONLY_PROPERTY";
+  case PROP_ERROR_INVALID_NAME: return "PROP_ERROR_INVALID_NAME";
+  case PROP_ERROR_INVALID_VALUE: return "PROP_ERROR_INVALID_VALUE";
+  case PROP_ERROR_PERMISSION_DENIED: return "PROP_ERROR_PERMISSION_DENIED";
+  case PROP_ERROR_INVALID_CMD: return "PROP_ERROR_INVALID_CMD";
+  case PROP_ERROR_HANDLE_CONTROL_MESSAGE: return "PROP_ERROR_HANDLE_CONTROL_MESSAGE";
+  case PROP_ERROR_SET_FAILED: return "PROP_ERROR_SET_FAILED";
+  }
+  return "<unknown>";
+}
+
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
 int __system_property_set(const char* key, const char* value) {
   if (key == nullptr) return -1;
@@ -310,8 +325,8 @@
 
     if (result != PROP_SUCCESS) {
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Unable to set property \"%s\" to \"%s\": error code: 0x%x", key, value,
-                            result);
+                            "Unable to set property \"%s\" to \"%s\": %s (0x%x)", key, value,
+                            __prop_error_to_string(result), result);
       return -1;
     }
 
diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c
index f4c590f..38de84b 100644
--- a/libc/dns/resolv/res_cache.c
+++ b/libc/dns/resolv/res_cache.c
@@ -1166,23 +1166,19 @@
     }
 }
 
-static __inline__ void
-entry_mru_remove( Entry*  e )
-{
-    e->mru_prev->mru_next = e->mru_next;
-    e->mru_next->mru_prev = e->mru_prev;
+static __inline__ void entry_mru_remove(Entry* e) {
+  e->mru_prev->mru_next = e->mru_next;
+  e->mru_next->mru_prev = e->mru_prev;
 }
 
-static __inline__ void
-entry_mru_add( Entry*  e, Entry*  list )
-{
-    Entry*  first = list->mru_next;
+static __inline__ void entry_mru_add(Entry* e, Entry* list) {
+  Entry* first = list->mru_next;
 
-    e->mru_next = first;
-    e->mru_prev = list;
+  e->mru_next = first;
+  e->mru_prev = list;
 
-    list->mru_next  = e;
-    first->mru_prev = e;
+  list->mru_next = e;
+  first->mru_prev = e;
 }
 
 /* compute the hash of a given entry, this is a hash of most
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 77ec653..1bde3a5 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -168,7 +168,10 @@
  */
 #define __ANDROID_API_U__ 34
 
-/** Names the "V" API level (35), for comparison against `__ANDROID_API__`. */
+/**
+ * Names the Android 15 (aka "V" or "VanillaIceCream") API level (35),
+ * for comparison against `__ANDROID_API__`.
+ */
 #define __ANDROID_API_V__ 35
 
 /* This file is included in <features.h>, and might be used from .S files. */
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index a5061c7..b42e5b2 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef __ANDROID_DLEXT_H__
-#define __ANDROID_DLEXT_H__
+#pragma once
 
 #include <stdbool.h>
 #include <stddef.h>
@@ -101,7 +100,7 @@
   ANDROID_DLEXT_FORCE_LOAD = 0x40,
 
   // Historically we had two other options for ART.
-  // They were last available in Android P.
+  // They were last available in API level 28.
   // Reuse these bits last!
   // ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80
   // ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100
@@ -115,7 +114,7 @@
   ANDROID_DLEXT_USE_NAMESPACE = 0x200,
 
   /**
-   * Instructs dlopen to apply `ANDROID_DLEXT_RESERVED_ADDRESS`,
+   * Instructs dlopen() to apply `ANDROID_DLEXT_RESERVED_ADDRESS`,
    * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`, `ANDROID_DLEXT_WRITE_RELRO` and
    * `ANDROID_DLEXT_USE_RELRO` to any libraries loaded as dependencies of the
    * main library as well.
@@ -151,7 +150,7 @@
 
 struct android_namespace_t;
 
-/** Used to pass Android-specific arguments to `android_dlopen_ext`. */
+/** Used to pass Android-specific arguments to android_dlopen_ext(). */
 typedef struct {
   /** A bitmask of `ANDROID_DLEXT_` enum values. */
   uint64_t flags;
@@ -183,5 +182,3 @@
 __END_DECLS
 
 /** @} */
-
-#endif
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index c5adc02..64528e1 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -20,15 +20,15 @@
 // we should only annotate headers when we are running versioner.
 #if defined(__BIONIC_VERSIONER)
 
-#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
-#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __attribute__((annotate("introduced_in=" #api_level))) __VERSIONER_NO_GUARD
-#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
-#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
-#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
-#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
+#define __INTRODUCED_IN(api_level) __attribute__((__annotate__("introduced_in=" #api_level)))
+#define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __attribute__((__annotate__("introduced_in=" #api_level))) __VERSIONER_NO_GUARD
+#define __DEPRECATED_IN(api_level, ...) __attribute__((__annotate__("deprecated_in=" #api_level)))
+#define __REMOVED_IN(api_level, ...) __attribute__((__annotate__("obsoleted_in=" #api_level)))
+#define __INTRODUCED_IN_32(api_level) __attribute__((__annotate__("introduced_in_32=" #api_level)))
+#define __INTRODUCED_IN_64(api_level) __attribute__((__annotate__("introduced_in_64=" #api_level)))
 
-#define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
-#define __VERSIONER_FORTIFY_INLINE __attribute__((annotate("versioner_fortify_inline")))
+#define __VERSIONER_NO_GUARD __attribute__((__annotate__("versioner_no_guard")))
+#define __VERSIONER_FORTIFY_INLINE __attribute__((__annotate__("versioner_fortify_inline")))
 
 #else
 
@@ -47,16 +47,16 @@
 // libc++ doesn't currently guard these calls. There's no risk to the apps though because using
 // those APIs will still cause a link error.
 #if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
-#define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,__what)))
+#define __BIONIC_AVAILABILITY(__what, ...) __attribute__((__availability__(android,__what __VA_OPT__(,) __VA_ARGS__)))
 #define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level) __INTRODUCED_IN(api_level)
 #else
-#define __BIONIC_AVAILABILITY(__what) __attribute__((__availability__(android,strict,__what)))
+#define __BIONIC_AVAILABILITY(__what, ...) __attribute__((__availability__(android,strict,__what __VA_OPT__(,) __VA_ARGS__)))
 #define __INTRODUCED_IN_NO_GUARD_FOR_NDK(api_level)
 #endif
 
 #define __INTRODUCED_IN(api_level) __BIONIC_AVAILABILITY(introduced=api_level)
-#define __DEPRECATED_IN(api_level) __BIONIC_AVAILABILITY(deprecated=api_level)
-#define __REMOVED_IN(api_level) __BIONIC_AVAILABILITY(obsoleted=api_level)
+#define __DEPRECATED_IN(api_level, ...) __BIONIC_AVAILABILITY(deprecated=api_level __VA_OPT__(,message=) __VA_ARGS__)
+#define __REMOVED_IN(api_level, ...) __BIONIC_AVAILABILITY(obsoleted=api_level __VA_OPT__(,message=) __VA_ARGS__)
 
 // The same availability attribute can't be annotated multiple times. Therefore, the macros are
 // defined for the configuration that it is valid for so that declarations like the below doesn't
@@ -80,5 +80,5 @@
 // Vendor modules do not follow SDK versioning. Ignore NDK guards for vendor modules.
 #if defined(__ANDROID_VENDOR__)
 #undef __BIONIC_AVAILABILITY
-#define __BIONIC_AVAILABILITY(x)
+#define __BIONIC_AVAILABILITY(api_level, ...)
 #endif // defined(__ANDROID_VENDOR__)
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index 83fb257..eceb334 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -552,6 +552,9 @@
 #if defined(__NR_listen)
   #define SYS_listen __NR_listen
 #endif
+#if defined(__NR_listmount)
+  #define SYS_listmount __NR_listmount
+#endif
 #if defined(__NR_listxattr)
   #define SYS_listxattr __NR_listxattr
 #endif
@@ -576,6 +579,15 @@
 #if defined(__NR_lsetxattr)
   #define SYS_lsetxattr __NR_lsetxattr
 #endif
+#if defined(__NR_lsm_get_self_attr)
+  #define SYS_lsm_get_self_attr __NR_lsm_get_self_attr
+#endif
+#if defined(__NR_lsm_list_modules)
+  #define SYS_lsm_list_modules __NR_lsm_list_modules
+#endif
+#if defined(__NR_lsm_set_self_attr)
+  #define SYS_lsm_set_self_attr __NR_lsm_set_self_attr
+#endif
 #if defined(__NR_lstat)
   #define SYS_lstat __NR_lstat
 #endif
@@ -1218,6 +1230,9 @@
 #if defined(__NR_statfs64)
   #define SYS_statfs64 __NR_statfs64
 #endif
+#if defined(__NR_statmount)
+  #define SYS_statmount __NR_statmount
+#endif
 #if defined(__NR_statx)
   #define SYS_statx __NR_statx
 #endif
diff --git a/libc/include/bits/page_size.h b/libc/include/bits/page_size.h
index df0cb7f..594ffe5 100644
--- a/libc/include/bits/page_size.h
+++ b/libc/include/bits/page_size.h
@@ -32,7 +32,16 @@
 
 __BEGIN_DECLS
 
-#if !defined(__BIONIC_NO_PAGE_SIZE_MACRO) || defined(__BIONIC_DEPRECATED_PAGE_SIZE_MACRO)
+// PAGE_SIZE is going away in Android. Prefer getpagesize() instead.
+//
+// For more info, see https://developer.android.com/16kb-page-size.
+//
+// To restore the original behavior, use __BIONIC_DEPRECATED_PAGE_SIZE_MACRO.
+
+#if (defined(__NDK_MAJOR__) && __NDK_MAJOR__ <= 27 && !defined(__BIONIC_NO_PAGE_SIZE_MACRO)) \
+    || defined(__BIONIC_DEPRECATED_PAGE_SIZE_MACRO) \
+    || defined(__arm__) \
+    || defined(__i386__)
 #define PAGE_SIZE 4096
 #define PAGE_MASK (~(PAGE_SIZE - 1))
 #endif
diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h
index fe3d68d..c74eafd 100644
--- a/libc/include/bits/stdatomic.h
+++ b/libc/include/bits/stdatomic.h
@@ -138,11 +138,11 @@
  * 7.17.4 Fences.
  */
 
-static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) {
+static __inline void atomic_thread_fence(memory_order __order __attribute__((__unused__))) {
 	__c11_atomic_thread_fence(__order);
 }
 
-static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) {
+static __inline void atomic_signal_fence(memory_order __order __attribute__((__unused__))) {
 	__c11_atomic_signal_fence(__order);
 }
 
diff --git a/libc/include/bits/struct_file.h b/libc/include/bits/struct_file.h
index abbd320..8cb8d28 100644
--- a/libc/include/bits/struct_file.h
+++ b/libc/include/bits/struct_file.h
@@ -39,6 +39,6 @@
 #else
   char __private[84];
 #endif
-} __attribute__((aligned(sizeof(void*))));
+} __attribute__((__aligned__(sizeof(void*))));
 
 __END_DECLS
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 5878e0a..459866e 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -124,7 +124,7 @@
 };
 #pragma clang diagnostic pop
 
-static inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
+static __inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
   struct __bionic_thrd_data __data =
       *__BIONIC_CAST(static_cast, struct __bionic_thrd_data*, __arg);
   free(__arg);
diff --git a/libc/include/limits.h b/libc/include/limits.h
index 48e7ea9..e1f566c 100644
--- a/libc/include/limits.h
+++ b/libc/include/limits.h
@@ -136,6 +136,9 @@
 #define IOV_MAX 1024
 #define SEM_VALUE_MAX 0x3fffffff
 
+/** Do not use: prefer getline() or asprintf() rather than hard-coding an arbitrary size. */
+#define LINE_MAX _POSIX2_LINE_MAX
+
 /* POSIX says these belong in <unistd.h> but BSD has some in <limits.h>. */
 #include <bits/posix_limits.h>
 
@@ -145,9 +148,15 @@
 
 /* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
 #define PTHREAD_DESTRUCTOR_ITERATIONS 4
-/* >= _POSIX_THREAD_KEYS_MAX */
+
+/**
+ * The number of calls to pthread_key_create() without intervening calls to
+ * pthread_key_delete() that are guaranteed to succeed. See pthread_key_create()
+ * for more details and ways to avoid hitting this limit.
+ */
 #define PTHREAD_KEYS_MAX 128
-/* bionic has no specific limit */
+
+/** bionic has no specific limit on the number of threads. */
 #undef PTHREAD_THREADS_MAX
 
 #endif /* !_LIMITS_H_ */
diff --git a/libc/include/link.h b/libc/include/link.h
index 33fea49..ee1fc42 100644
--- a/libc/include/link.h
+++ b/libc/include/link.h
@@ -25,8 +25,13 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#ifndef _LINK_H_
-#define _LINK_H_
+
+#pragma once
+
+/**
+ * @file link.h
+ * @brief Extra dynamic linker functionality (see also <dlfcn.h>).
+ */
 
 #include <stdint.h>
 #include <sys/cdefs.h>
@@ -37,32 +42,80 @@
 __BEGIN_DECLS
 
 #if defined(__LP64__)
+/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */
 #define ElfW(type) Elf64_ ## type
 #else
+/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */
 #define ElfW(type) Elf32_ ## type
 #endif
 
+/**
+ * Information passed by dl_iterate_phdr() to the callback.
+ */
 struct dl_phdr_info {
+  /** The address of the shared object. */
   ElfW(Addr) dlpi_addr;
+  /** The name of the shared object. */
   const char* _Nullable dlpi_name;
+  /** Pointer to the shared object's program headers. */
   const ElfW(Phdr)* _Nullable dlpi_phdr;
+  /** Number of program headers pointed to by `dlpi_phdr`. */
   ElfW(Half) dlpi_phnum;
 
-  // These fields were added in Android R.
+  /**
+   * The total number of library load events at the time dl_iterate_phdr() was
+   * called.
+   *
+   * This field is only available since API level 30; you can use the size
+   * passed to the callback to determine whether you have the full struct,
+   * or just the fields up to and including `dlpi_phnum`.
+   */
   unsigned long long dlpi_adds;
+  /**
+   * The total number of library unload events at the time dl_iterate_phdr() was
+   * called.
+   *
+   * This field is only available since API level 30; you can use the size
+   * passed to the callback to determine whether you have the full struct,
+   * or just the fields up to and including `dlpi_phnum`.
+   */
   unsigned long long dlpi_subs;
+  /**
+   * The module ID for TLS relocations in this shared object.
+   *
+   * This field is only available since API level 30; you can use the size
+   * passed to the callback to determine whether you have the full struct,
+   * or just the fields up to and including `dlpi_phnum`.
+   */
   size_t dlpi_tls_modid;
+  /**
+   * The caller's TLS data for this shared object.
+   *
+   * This field is only available since API level 30; you can use the size
+   * passed to the callback to determine whether you have the full struct,
+   * or just the fields up to and including `dlpi_phnum`.
+   */
   void* _Nullable dlpi_tls_data;
 };
 
-int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void* _Nullable), void* _Nullable __data);
+/**
+ * [dl_iterate_phdr(3)](http://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html)
+ * calls the given callback once for every loaded shared object. The size
+ * argument to the callback lets you determine whether you have a smaller
+ * `dl_phdr_info` from before API level 30, or the newer full one.
+ * The data argument to the callback is whatever you pass as the data argument
+ * to dl_iterate_phdr().
+ *
+ * Returns the value returned by the final call to the callback.
+ */
+int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull __info, size_t __size, void* _Nullable __data), void* _Nullable __data);
 
 #ifdef __arm__
 typedef uintptr_t _Unwind_Ptr;
 _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull);
 #endif
 
-/* Used by the dynamic linker to communicate with the debugger. */
+/** Used by the dynamic linker to communicate with the debugger. */
 struct link_map {
   ElfW(Addr) l_addr;
   char* _Nullable l_name;
@@ -71,7 +124,7 @@
   struct link_map* _Nullable l_prev;
 };
 
-/* Used by the dynamic linker to communicate with the debugger. */
+/** Used by the dynamic linker to communicate with the debugger. */
 struct r_debug {
   int32_t r_version;
   struct link_map* _Nullable r_map;
@@ -85,5 +138,3 @@
 };
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index d22b85c..ef1e27d 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -186,7 +186,11 @@
 int malloc_info(int __must_be_zero, FILE* _Nonnull __fp) __INTRODUCED_IN(23);
 
 /**
- * mallopt() option to set the decay time. Valid values are 0 and 1.
+ * mallopt() option to set the decay time. Valid values are -1, 0 and 1.
+ *   -1 : Disable the releasing of unused pages. This value is available since
+ *        API level 35.
+ *    0 : Release the unused pages immediately.
+ *    1 : Release the unused pages at a device-specific interval.
  *
  * Available since API level 27.
  */
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 871c62c..ef41e2d 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -174,7 +174,29 @@
 
 int pthread_join(pthread_t __pthread, void* _Nullable * _Nullable __return_value_ptr);
 
+/**
+ * [pthread_key_create(3)](https://man7.org/linux/man-pages/man3/pthread_key_create.3p.html)
+ * creates a key for thread-specific data.
+ *
+ * There is a limit of `PTHREAD_KEYS_MAX` keys per process, but most callers
+ * should just use the C or C++ `thread_local` storage specifier anyway. When
+ * targeting new enough OS versions, the compiler will automatically use
+ * ELF TLS; when targeting old OS versions the emutls implementation will
+ * multiplex pthread keys behind the scenes, using one per library rather than
+ * one per thread-local variable. If you are implementing the runtime for a
+ * different language, you should consider similar implementation choices and
+ * avoid a direct one-to-one mapping from thread locals to pthread keys.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ */
 int pthread_key_create(pthread_key_t* _Nonnull __key_ptr, void (* _Nullable __key_destructor)(void* _Nullable));
+
+/**
+ * [pthread_key_delete(3)](https://man7.org/linux/man-pages/man3/pthread_key_delete.3p.html)
+ * deletes a key for thread-specific data.
+ *
+ * Returns 0 on success and returns an error number on failure.
+ */
 int pthread_key_delete(pthread_key_t __key);
 
 int pthread_mutexattr_destroy(pthread_mutexattr_t* _Nonnull __attr);
diff --git a/libc/include/sched.h b/libc/include/sched.h
index b1f1842..9f043b6 100644
--- a/libc/include/sched.h
+++ b/libc/include/sched.h
@@ -99,7 +99,7 @@
 };
 
 /**
- * [sched_setscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
+ * [sched_setscheduler(2)](https://man7.org/linux/man-pages/man2/sched_setscheduler.2.html)
  * sets the scheduling policy and associated parameters for the given thread.
  *
  * Returns 0 on success and returns -1 and sets `errno` on failure.
@@ -107,7 +107,7 @@
 int sched_setscheduler(pid_t __pid, int __policy, const struct sched_param* _Nonnull __param);
 
 /**
- * [sched_getscheduler(2)](http://man7.org/linux/man-pages/man2/sched_getcpu.2.html)
+ * [sched_getscheduler(2)](https://man7.org/linux/man-pages/man2/sched_getscheduler.2)
  * gets the scheduling policy for the given thread.
  *
  * Returns a non-negative thread policy on success and returns -1 and sets
diff --git a/libc/include/signal.h b/libc/include/signal.h
index cf83db8..9d47bcc 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -86,17 +86,17 @@
 int sigwait64(const sigset64_t* _Nonnull __set, int* _Nonnull __signal) __INTRODUCED_IN(28);
 
 int sighold(int __signal)
-  __attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
+  __attribute__((__deprecated__("use sigprocmask() or pthread_sigmask() instead")))
   __INTRODUCED_IN(26);
 int sigignore(int __signal)
-  __attribute__((deprecated("use sigaction() instead"))) __INTRODUCED_IN(26);
+  __attribute__((__deprecated__("use sigaction() instead"))) __INTRODUCED_IN(26);
 int sigpause(int __signal)
-  __attribute__((deprecated("use sigsuspend() instead"))) __INTRODUCED_IN(26);
+  __attribute__((__deprecated__("use sigsuspend() instead"))) __INTRODUCED_IN(26);
 int sigrelse(int __signal)
-  __attribute__((deprecated("use sigprocmask() or pthread_sigmask() instead")))
+  __attribute__((__deprecated__("use sigprocmask() or pthread_sigmask() instead")))
   __INTRODUCED_IN(26);
 sighandler_t _Nonnull sigset(int __signal, sighandler_t _Nullable __handler)
-  __attribute__((deprecated("use sigaction() instead"))) __INTRODUCED_IN(26);
+  __attribute__((__deprecated__("use sigaction() instead"))) __INTRODUCED_IN(26);
 
 int raise(int __signal);
 int kill(pid_t __pid, int __signal);
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 312b356..78114c3 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -69,7 +69,7 @@
 #define stderr stderr
 #else
 /* Before M the actual symbols for stdin and friends had different names. */
-extern FILE __sF[] __REMOVED_IN(23);
+extern FILE __sF[] __REMOVED_IN(23, "Use stdin/stdout/stderr");
 
 #define stdin (&__sF[0])
 #define stdout (&__sF[1])
@@ -141,7 +141,7 @@
 
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
     (defined(__cplusplus) && __cplusplus <= 201103L)
-char* _Nullable gets(char* _Nonnull __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
+char* _Nullable gets(char* _Nonnull __buf) __attribute__((__deprecated__("gets is unsafe, use fgets instead")));
 #endif
 int sprintf(char* __BIONIC_COMPLICATED_NULLNESS __s, const char* _Nonnull __fmt, ...)
     __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 2830a49..506ab43 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -57,7 +57,7 @@
 int clearenv(void);
 
 char* _Nullable mkdtemp(char* _Nonnull __template);
-char* _Nullable mktemp(char* _Nonnull __template) __attribute__((deprecated("mktemp is unsafe, use mkstemp or tmpfile instead")));
+char* _Nullable mktemp(char* _Nonnull __template) __attribute__((__deprecated__("mktemp is unsafe, use mkstemp or tmpfile instead")));
 
 int mkostemp64(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
 int mkostemp(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23);
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 2f4f764..4b8cc08 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -61,13 +61,13 @@
 
 /** Deprecated. Use memmove() instead. */
 #define bcopy(b1, b2, len) __bionic_bcopy((b1), (b2), (len))
-static __inline__ __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) {
+static __inline __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) {
   __builtin_memmove(b2, b1, len);
 }
 
 /** Deprecated. Use memset() instead. */
 #define bzero(b, len) __bionic_bzero((b), (len))
-static __inline__ __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) {
+static __inline __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) {
   __builtin_memset(b, 0, len);
 }
 
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index a8fb624..5d1718e 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -87,9 +87,12 @@
 #define	__STRING(x)	#x
 #define	___STRING(x)	__STRING(x)
 
-#if defined(__cplusplus)
-#define	__inline	inline		/* convert to C++ keyword */
-#endif /* !__cplusplus */
+// C++ has `inline` as a keyword, as does C99, but ANSI C (aka C89 aka C90)
+// does not. Everything accepts the `__inline__` extension though. We could
+// just use that directly in our own code, but there's historical precedent
+// for `__inline` meaning it's still used in upstream BSD code (and potentially
+// downstream in vendor or app code).
+#define	__inline __inline__
 
 #define __always_inline __attribute__((__always_inline__))
 #define __attribute_const__ __attribute__((__const__))
@@ -139,12 +142,12 @@
 
 #define __wur __attribute__((__warn_unused_result__))
 
-#define __errorattr(msg) __attribute__((unavailable(msg)))
-#define __warnattr(msg) __attribute__((deprecated(msg)))
-#define __warnattr_real(msg) __attribute__((deprecated(msg)))
-#define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
-#define __clang_error_if(cond, msg) __attribute__((diagnose_if(cond, msg, "error")))
-#define __clang_warning_if(cond, msg) __attribute__((diagnose_if(cond, msg, "warning")))
+#define __errorattr(msg) __attribute__((__unavailable__(msg)))
+#define __warnattr(msg) __attribute__((__deprecated__(msg)))
+#define __warnattr_real(msg) __attribute__((__deprecated__(msg)))
+#define __enable_if(cond, msg) __attribute__((__enable_if__(cond, msg)))
+#define __clang_error_if(cond, msg) __attribute__((__diagnose_if__(cond, msg, "error")))
+#define __clang_warning_if(cond, msg) __attribute__((__diagnose_if__(cond, msg, "warning")))
 
 #if defined(ANDROID_STRICT)
 /*
@@ -248,7 +251,7 @@
 
 #if defined(__BIONIC_FORTIFY)
 #  define __bos0(s) __bosn((s), 0)
-#  define __pass_object_size_n(n) __attribute__((pass_object_size(n)))
+#  define __pass_object_size_n(n) __attribute__((__pass_object_size__(n)))
 /*
  * FORTIFY'ed functions all have either enable_if or pass_object_size, which
  * makes taking their address impossible. Saying (&read)(foo, bar, baz); will
@@ -260,7 +263,7 @@
  * them available externally. FORTIFY'ed functions try to be as close to possible as 'invisible';
  * having stack protectors detracts from that (b/182948263).
  */
-#  define __BIONIC_FORTIFY_INLINE static __inline__ __attribute__((no_stack_protector)) \
+#  define __BIONIC_FORTIFY_INLINE static __inline __attribute__((__no_stack_protector__)) \
       __always_inline __VERSIONER_FORTIFY_INLINE
 /*
  * We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
@@ -268,9 +271,9 @@
  * The __always_inline attribute is useless, misleading, and could trigger
  * clang compiler bug to incorrectly inline variadic functions.
  */
-#  define __BIONIC_FORTIFY_VARIADIC static __inline__
+#  define __BIONIC_FORTIFY_VARIADIC static __inline
 /* Error functions don't have bodies, so they can just be static. */
-#  define __BIONIC_ERROR_FUNCTION_VISIBILITY static __attribute__((unused))
+#  define __BIONIC_ERROR_FUNCTION_VISIBILITY static __unused
 #else
 /* Further increase sharing for some inline functions */
 #  define __pass_object_size_n(n)
@@ -300,47 +303,32 @@
 #  define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
 #endif
 
-#define __overloadable __attribute__((overloadable))
+#define __overloadable __attribute__((__overloadable__))
 
-#define __diagnose_as_builtin(...) __attribute__((diagnose_as_builtin(__VA_ARGS__)))
+#define __diagnose_as_builtin(...) __attribute__((__diagnose_as_builtin__(__VA_ARGS__)))
 
 /* Used to tag non-static symbols that are private and never exposed by the shared library. */
-#define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
+#define __LIBC_HIDDEN__ __attribute__((__visibility__("hidden")))
 
 /*
  * Used to tag symbols that should be hidden for 64-bit,
  * but visible to preserve binary compatibility for LP32.
  */
 #ifdef __LP64__
-#define __LIBC32_LEGACY_PUBLIC__ __attribute__((visibility("hidden")))
+#define __LIBC32_LEGACY_PUBLIC__ __attribute__((__visibility__("hidden")))
 #else
-#define __LIBC32_LEGACY_PUBLIC__ __attribute__((visibility("default")))
+#define __LIBC32_LEGACY_PUBLIC__ __attribute__((__visibility__("default")))
 #endif
 
 /* Used to rename functions so that the compiler emits a call to 'x' rather than the function this was applied to. */
 #define __RENAME(x) __asm__(#x)
 
-#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
-#if defined(__LP64__)
-#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result)
-#else
-#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result)
-#endif
-#else
-extern __inline__ __always_inline __attribute__((gnu_inline))
-int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) {
-    *result = a * b;
-    static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4);
-    return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b;
-}
-#endif
-
 /*
  * Used when we need to check for overflow when multiplying x and y. This
- * should only be used where __size_mul_overflow can not work, because it makes
- * assumptions that __size_mul_overflow doesn't (x and y are positive, ...),
+ * should only be used where __builtin_umull_overflow can not work, because it makes
+ * assumptions that __builtin_umull_overflow doesn't (x and y are positive, ...),
  * *and* doesn't make use of compiler intrinsics, so it's probably slower than
- * __size_mul_overflow.
+ * __builtin_umull_overflow.
  */
 #define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
 
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index 79ae067..1c991ae 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -41,8 +41,11 @@
 /** The unit of `st_blocks` in `struct stat`. */
 #define DEV_BSIZE 512
 
-/** A historical name for PATH_MAX. */
-#define MAXPATHLEN  PATH_MAX
+/** A historical name for PATH_MAX. Use PATH_MAX in new code. */
+#define MAXPATHLEN PATH_MAX
+
+/** A historical name for NGROUPS_MAX. Use NGROUPS_MAX in new code. */
+#define NGROUPS NGROUPS_MAX
 
 #define MAXSYMLINKS 8
 
diff --git a/libc/include/sys/shm.h b/libc/include/sys/shm.h
index fb6f20c..8ab3d9a 100644
--- a/libc/include/sys/shm.h
+++ b/libc/include/sys/shm.h
@@ -36,11 +36,12 @@
 #include <sys/cdefs.h>
 #include <sys/ipc.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <linux/shm.h>
 
 #define shmid_ds shmid64_ds
-#define SHMLBA 4096
+#define SHMLBA getpagesize()
 
 __BEGIN_DECLS
 
diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h
index dc869da..ae94db5 100644
--- a/libc/include/sys/system_properties.h
+++ b/libc/include/sys/system_properties.h
@@ -26,8 +26,12 @@
  * SUCH DAMAGE.
  */
 
-#ifndef _INCLUDE_SYS_SYSTEM_PROPERTIES_H
-#define _INCLUDE_SYS_SYSTEM_PROPERTIES_H
+#pragma once
+
+/**
+ * @file system_properties.h
+ * @brief System properties.
+ */
 
 #include <sys/cdefs.h>
 #include <stdbool.h>
@@ -36,39 +40,53 @@
 
 __BEGIN_DECLS
 
+/** An opaque structure representing a system property. */
 typedef struct prop_info prop_info;
 
+/**
+ * The limit on the length of a property value.
+ * (See PROP_NAME_MAX for property names.)
+ */
 #define PROP_VALUE_MAX  92
 
-/*
+/**
  * Sets system property `name` to `value`, creating the system property if it doesn't already exist.
+ *
+ * Returns 0 on success, or -1 on failure.
  */
 int __system_property_set(const char* _Nonnull __name, const char* _Nonnull __value);
 
-/*
+/**
  * Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist.
- * Use __system_property_read_callback to query the current value.
+ * Use __system_property_read_callback() to query the current value.
  *
- * Property lookup is expensive, so it can be useful to cache the result of this function.
+ * Property lookup is expensive, so it can be useful to cache the result of this
+ * function rather than using __system_property_get().
  */
 const prop_info* _Nullable __system_property_find(const char* _Nonnull __name);
 
-/*
- * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`.
+/**
+ * Calls `callback` with a consistent trio of name, value, and serial number
+ * for property `pi`.
+ *
+ * Available since API level 26.
  */
 void __system_property_read_callback(const prop_info* _Nonnull __pi,
     void (* _Nonnull __callback)(void* _Nullable __cookie, const char* _Nonnull __name, const char* _Nonnull __value, uint32_t __serial),
     void* _Nullable __cookie) __INTRODUCED_IN(26);
 
-/*
+/**
  * Passes a `prop_info` for each system property to the provided
- * callback.  Use __system_property_read_callback() to read the value.
+ * callback. Use __system_property_read_callback() to read the value of
+ * any of the properties.
  *
  * This method is for inspecting and debugging the property system, and not generally useful.
+ *
+ * Returns 0 on success, or -1 on failure.
  */
 int __system_property_foreach(void (* _Nonnull __callback)(const prop_info* _Nonnull __pi, void* _Nullable __cookie), void* _Nullable __cookie);
 
-/*
+/**
  * Waits for the specific system property identified by `pi` to be updated
  * past `old_serial`. Waits no longer than `relative_timeout`, or forever
  * if `relative_timeout` is null.
@@ -79,20 +97,24 @@
  *
  * Returns true and updates `*new_serial_ptr` on success, or false if the call
  * timed out.
+ *
+ * Available since API level 26.
  */
 struct timespec;
 bool __system_property_wait(const prop_info* _Nullable __pi, uint32_t __old_serial, uint32_t* _Nonnull __new_serial_ptr, const struct timespec* _Nullable __relative_timeout)
     __INTRODUCED_IN(26);
 
-/* Deprecated. In Android O and above, there's no limit on property name length. */
+/**
+ * Deprecated: there's no limit on the length of a property name since
+ * API level 26, though the limit on property values (PROP_VALUE_MAX) remains.
+ */
 #define PROP_NAME_MAX   32
-/* Deprecated. Use __system_property_read_callback instead. */
+
+/** Deprecated. Use __system_property_read_callback() instead. */
 int __system_property_read(const prop_info* _Nonnull __pi, char* _Nullable __name, char* _Nonnull __value);
-/* Deprecated. Use __system_property_read_callback instead. */
+/** Deprecated. Use __system_property_read_callback() instead. */
 int __system_property_get(const char* _Nonnull __name, char* _Nonnull __value);
-/* Deprecated. Use __system_property_foreach instead. */
+/** Deprecated. Use __system_property_foreach() instead. */
 const prop_info* _Nullable __system_property_find_nth(unsigned __n);
 
 __END_DECLS
-
-#endif
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index c69db61..2732214 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -350,8 +350,11 @@
 int daemon(int __no_chdir, int __no_close);
 
 #if defined(__arm__)
+/**
+ * New code should use __builtin___clear_cache() instead, which works on
+ * all architectures.
+ */
 int cacheflush(long __addr, long __nbytes, long __cache);
-    /* __attribute__((deprecated("use __builtin___clear_cache instead"))); */
 #endif
 
 pid_t tcgetpgrp(int __fd);
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 1d7b427..06afb25 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -32,8 +32,10 @@
 # addition to removing the structure, add a #include to the file.
 kernel_structs_to_remove = {
     # Remove these structures since they are still the same as
-    # timeval, itimerval.
-    "__kernel_old_timeval": None,
+    # timeval, itimerval. Also, add an include of linux/time.h
+    # since __kernel_old_timeval is being changed to timeval, and
+    # is only present in linux/time.h.
+    "__kernel_old_timeval": "linux/time.h",
     "__kernel_old_itimerval": None,
     # Replace all of the below structures with #include <bits/STRUCT.h>
     "__kernel_sockaddr_storage": "bits/sockaddr_storage.h",
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
index 482b9cb..1032131 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-eabi.h
@@ -415,4 +415,9 @@
 #define __NR_futex_wake (__NR_SYSCALL_BASE + 454)
 #define __NR_futex_wait (__NR_SYSCALL_BASE + 455)
 #define __NR_futex_requeue (__NR_SYSCALL_BASE + 456)
+#define __NR_statmount (__NR_SYSCALL_BASE + 457)
+#define __NR_listmount (__NR_SYSCALL_BASE + 458)
+#define __NR_lsm_get_self_attr (__NR_SYSCALL_BASE + 459)
+#define __NR_lsm_set_self_attr (__NR_SYSCALL_BASE + 460)
+#define __NR_lsm_list_modules (__NR_SYSCALL_BASE + 461)
 #endif
diff --git a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
index 5126831..1f57604 100644
--- a/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
+++ b/libc/kernel/uapi/asm-arm/asm/unistd-oabi.h
@@ -427,4 +427,9 @@
 #define __NR_futex_wake (__NR_SYSCALL_BASE + 454)
 #define __NR_futex_wait (__NR_SYSCALL_BASE + 455)
 #define __NR_futex_requeue (__NR_SYSCALL_BASE + 456)
+#define __NR_statmount (__NR_SYSCALL_BASE + 457)
+#define __NR_listmount (__NR_SYSCALL_BASE + 458)
+#define __NR_lsm_get_self_attr (__NR_SYSCALL_BASE + 459)
+#define __NR_lsm_set_self_attr (__NR_SYSCALL_BASE + 460)
+#define __NR_lsm_list_modules (__NR_SYSCALL_BASE + 461)
 #endif
diff --git a/libc/kernel/uapi/asm-generic/unistd.h b/libc/kernel/uapi/asm-generic/unistd.h
index 717a098..c882751 100644
--- a/libc/kernel/uapi/asm-generic/unistd.h
+++ b/libc/kernel/uapi/asm-generic/unistd.h
@@ -407,8 +407,13 @@
 #define __NR_futex_wake 454
 #define __NR_futex_wait 455
 #define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
 #undef __NR_syscalls
-#define __NR_syscalls 457
+#define __NR_syscalls 462
 #if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
 #define __NR_fcntl __NR3264_fcntl
 #define __NR_statfs __NR3264_statfs
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
index a18b020..6f8d8f5 100644
--- a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -24,6 +24,35 @@
 #define RISCV_HWPROBE_EXT_ZBB (1 << 4)
 #define RISCV_HWPROBE_EXT_ZBS (1 << 5)
 #define RISCV_HWPROBE_EXT_ZICBOZ (1 << 6)
+#define RISCV_HWPROBE_EXT_ZBC (1 << 7)
+#define RISCV_HWPROBE_EXT_ZBKB (1 << 8)
+#define RISCV_HWPROBE_EXT_ZBKC (1 << 9)
+#define RISCV_HWPROBE_EXT_ZBKX (1 << 10)
+#define RISCV_HWPROBE_EXT_ZKND (1 << 11)
+#define RISCV_HWPROBE_EXT_ZKNE (1 << 12)
+#define RISCV_HWPROBE_EXT_ZKNH (1 << 13)
+#define RISCV_HWPROBE_EXT_ZKSED (1 << 14)
+#define RISCV_HWPROBE_EXT_ZKSH (1 << 15)
+#define RISCV_HWPROBE_EXT_ZKT (1 << 16)
+#define RISCV_HWPROBE_EXT_ZVBB (1 << 17)
+#define RISCV_HWPROBE_EXT_ZVBC (1 << 18)
+#define RISCV_HWPROBE_EXT_ZVKB (1 << 19)
+#define RISCV_HWPROBE_EXT_ZVKG (1 << 20)
+#define RISCV_HWPROBE_EXT_ZVKNED (1 << 21)
+#define RISCV_HWPROBE_EXT_ZVKNHA (1 << 22)
+#define RISCV_HWPROBE_EXT_ZVKNHB (1 << 23)
+#define RISCV_HWPROBE_EXT_ZVKSED (1 << 24)
+#define RISCV_HWPROBE_EXT_ZVKSH (1 << 25)
+#define RISCV_HWPROBE_EXT_ZVKT (1 << 26)
+#define RISCV_HWPROBE_EXT_ZFH (1 << 27)
+#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
+#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
+#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
+#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31)
+#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
+#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
+#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
+#define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
 #define RISCV_HWPROBE_KEY_CPUPERF_0 5
 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
 #define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
@@ -32,4 +61,5 @@
 #define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
 #define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
 #define RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE 6
+#define RISCV_HWPROBE_WHICH_CPUS (1 << 0)
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
index 470d581..054e1a1 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -99,6 +99,33 @@
   KVM_RISCV_ISA_EXT_ZIHPM,
   KVM_RISCV_ISA_EXT_SMSTATEEN,
   KVM_RISCV_ISA_EXT_ZICOND,
+  KVM_RISCV_ISA_EXT_ZBC,
+  KVM_RISCV_ISA_EXT_ZBKB,
+  KVM_RISCV_ISA_EXT_ZBKC,
+  KVM_RISCV_ISA_EXT_ZBKX,
+  KVM_RISCV_ISA_EXT_ZKND,
+  KVM_RISCV_ISA_EXT_ZKNE,
+  KVM_RISCV_ISA_EXT_ZKNH,
+  KVM_RISCV_ISA_EXT_ZKR,
+  KVM_RISCV_ISA_EXT_ZKSED,
+  KVM_RISCV_ISA_EXT_ZKSH,
+  KVM_RISCV_ISA_EXT_ZKT,
+  KVM_RISCV_ISA_EXT_ZVBB,
+  KVM_RISCV_ISA_EXT_ZVBC,
+  KVM_RISCV_ISA_EXT_ZVKB,
+  KVM_RISCV_ISA_EXT_ZVKG,
+  KVM_RISCV_ISA_EXT_ZVKNED,
+  KVM_RISCV_ISA_EXT_ZVKNHA,
+  KVM_RISCV_ISA_EXT_ZVKNHB,
+  KVM_RISCV_ISA_EXT_ZVKSED,
+  KVM_RISCV_ISA_EXT_ZVKSH,
+  KVM_RISCV_ISA_EXT_ZVKT,
+  KVM_RISCV_ISA_EXT_ZFH,
+  KVM_RISCV_ISA_EXT_ZFHMIN,
+  KVM_RISCV_ISA_EXT_ZIHINTNTL,
+  KVM_RISCV_ISA_EXT_ZVFH,
+  KVM_RISCV_ISA_EXT_ZVFHMIN,
+  KVM_RISCV_ISA_EXT_ZFA,
   KVM_RISCV_ISA_EXT_MAX,
 };
 enum KVM_RISCV_SBI_EXT_ID {
@@ -112,8 +139,13 @@
   KVM_RISCV_SBI_EXT_EXPERIMENTAL,
   KVM_RISCV_SBI_EXT_VENDOR,
   KVM_RISCV_SBI_EXT_DBCN,
+  KVM_RISCV_SBI_EXT_STA,
   KVM_RISCV_SBI_EXT_MAX,
 };
+struct kvm_riscv_sbi_sta {
+  unsigned long shmem_lo;
+  unsigned long shmem_hi;
+};
 #define KVM_RISCV_TIMER_STATE_OFF 0
 #define KVM_RISCV_TIMER_STATE_ON 1
 #define KVM_REG_SIZE(id) (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
@@ -155,6 +187,9 @@
 #define KVM_REG_RISCV_VECTOR (0x09 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_VECTOR_CSR_REG(name) (offsetof(struct __riscv_v_ext_state, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_VECTOR_REG(n) ((n) + sizeof(struct __riscv_v_ext_state) / sizeof(unsigned long))
+#define KVM_REG_RISCV_SBI_STATE (0x0a << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_STA (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_STA_REG(name) (offsetof(struct kvm_riscv_sbi_sta, name) / sizeof(unsigned long))
 #define KVM_DEV_RISCV_APLIC_ALIGN 0x1000
 #define KVM_DEV_RISCV_APLIC_SIZE 0x4000
 #define KVM_DEV_RISCV_APLIC_MAX_HARTS 0x4000
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 334fb25..1dd057a 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -409,4 +409,6 @@
 #define KVM_VCPU_TSC_CTRL 0
 #define KVM_VCPU_TSC_OFFSET 0
 #define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0)
+#define KVM_X86_DEFAULT_VM 0
+#define KVM_X86_SW_PROTECTED_VM 1
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/signal.h b/libc/kernel/uapi/asm-x86/asm/signal.h
index 96ac8fb..6cffef3 100644
--- a/libc/kernel/uapi/asm-x86/asm/signal.h
+++ b/libc/kernel/uapi/asm-x86/asm/signal.h
@@ -8,7 +8,6 @@
 #define _UAPI_ASM_X86_SIGNAL_H
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
-#include <linux/time.h>
 #include <linux/compiler.h>
 struct siginfo;
 #define _KERNEL_NSIG 32
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_32.h b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
index e82b988..72076fd 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_32.h
@@ -452,4 +452,9 @@
 #define __NR_futex_wake 454
 #define __NR_futex_wait 455
 #define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_64.h b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
index 10d6e96..8c4f76e 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_64.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_64.h
@@ -374,4 +374,9 @@
 #define __NR_futex_wake 454
 #define __NR_futex_wait 455
 #define __NR_futex_requeue 456
+#define __NR_statmount 457
+#define __NR_listmount 458
+#define __NR_lsm_get_self_attr 459
+#define __NR_lsm_set_self_attr 460
+#define __NR_lsm_list_modules 461
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
index 7fbbe11..984cfca 100644
--- a/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
+++ b/libc/kernel/uapi/asm-x86/asm/unistd_x32.h
@@ -326,6 +326,11 @@
 #define __NR_futex_wake (__X32_SYSCALL_BIT + 454)
 #define __NR_futex_wait (__X32_SYSCALL_BIT + 455)
 #define __NR_futex_requeue (__X32_SYSCALL_BIT + 456)
+#define __NR_statmount (__X32_SYSCALL_BIT + 457)
+#define __NR_listmount (__X32_SYSCALL_BIT + 458)
+#define __NR_lsm_get_self_attr (__X32_SYSCALL_BIT + 459)
+#define __NR_lsm_set_self_attr (__X32_SYSCALL_BIT + 460)
+#define __NR_lsm_list_modules (__X32_SYSCALL_BIT + 461)
 #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
 #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
 #define __NR_ioctl (__X32_SYSCALL_BIT + 514)
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 0fe5c26..c8fab3c 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -353,6 +353,7 @@
 #define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
 #define DRM_CAP_SYNCOBJ 0x13
 #define DRM_CAP_SYNCOBJ_TIMELINE 0x14
+#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15
 struct drm_get_cap {
   __u64 capability;
   __u64 value;
@@ -362,6 +363,7 @@
 #define DRM_CLIENT_CAP_ATOMIC 3
 #define DRM_CLIENT_CAP_ASPECT_RATIO 4
 #define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5
+#define DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 6
 struct drm_set_client_cap {
   __u64 capability;
   __u64 value;
@@ -401,6 +403,7 @@
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
 #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE (1 << 3)
 struct drm_syncobj_wait {
   __u64 handles;
   __s64 timeout_nsec;
@@ -408,6 +411,7 @@
   __u32 flags;
   __u32 first_signaled;
   __u32 pad;
+  __u64 deadline_nsec;
 };
 struct drm_syncobj_timeline_wait {
   __u64 handles;
@@ -417,6 +421,7 @@
   __u32 flags;
   __u32 first_signaled;
   __u32 pad;
+  __u64 deadline_nsec;
 };
 struct drm_syncobj_eventfd {
   __u32 handle;
@@ -570,6 +575,7 @@
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
 #define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2)
 #define DRM_IOCTL_SYNCOBJ_EVENTFD DRM_IOWR(0xCF, struct drm_syncobj_eventfd)
+#define DRM_IOCTL_MODE_CLOSEFB DRM_IOWR(0xD0, struct drm_mode_closefb)
 #define DRM_COMMAND_BASE 0x40
 #define DRM_COMMAND_END 0xA0
 struct drm_event {
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index f7b65b2..9e6296c 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -357,6 +357,9 @@
 struct drm_color_ctm {
   __u64 matrix[9];
 };
+struct drm_color_ctm_3x4 {
+  __u64 matrix[12];
+};
 struct drm_color_lut {
   __u16 red;
   __u16 green;
@@ -483,6 +486,10 @@
   __s32 x2;
   __s32 y2;
 };
+struct drm_mode_closefb {
+  __u32 fb_id;
+  __u32 pad;
+};
 #ifdef __cplusplus
 }
 #endif
diff --git a/libc/kernel/uapi/drm/habanalabs_accel.h b/libc/kernel/uapi/drm/habanalabs_accel.h
index 158e937..47afb82 100644
--- a/libc/kernel/uapi/drm/habanalabs_accel.h
+++ b/libc/kernel/uapi/drm/habanalabs_accel.h
@@ -656,6 +656,7 @@
 #define HL_INFO_HW_ERR_EVENT 36
 #define HL_INFO_FW_ERR_EVENT 37
 #define HL_INFO_USER_ENGINE_ERR_EVENT 38
+#define HL_INFO_DEV_SIGNED 40
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 #define HL_ENGINES_DATA_MAX_SIZE SZ_1M
@@ -849,6 +850,7 @@
 #define SEC_SIGNATURE_BUF_SZ 255
 #define SEC_PUB_DATA_BUF_SZ 510
 #define SEC_CERTIFICATE_BUF_SZ 2046
+#define SEC_DEV_INFO_BUF_SZ 5120
 struct hl_info_sec_attest {
   __u32 nonce;
   __u16 pcr_quote_len;
@@ -864,6 +866,18 @@
   __u8 certificate[SEC_CERTIFICATE_BUF_SZ];
   __u8 pad0[2];
 };
+struct hl_info_signed {
+  __u32 nonce;
+  __u16 pub_data_len;
+  __u16 certificate_len;
+  __u8 info_sig_len;
+  __u8 public_data[SEC_PUB_DATA_BUF_SZ];
+  __u8 certificate[SEC_CERTIFICATE_BUF_SZ];
+  __u8 info_sig[SEC_SIGNATURE_BUF_SZ];
+  __u16 dev_info_len;
+  __u8 dev_info[SEC_DEV_INFO_BUF_SZ];
+  __u8 pad[2];
+};
 struct hl_page_fault_info {
   __s64 timestamp;
   __u64 addr;
diff --git a/libc/kernel/uapi/drm/ivpu_accel.h b/libc/kernel/uapi/drm/ivpu_accel.h
index ca2014f..fcbf6f7 100644
--- a/libc/kernel/uapi/drm/ivpu_accel.h
+++ b/libc/kernel/uapi/drm/ivpu_accel.h
@@ -43,6 +43,11 @@
 #define DRM_IVPU_CONTEXT_PRIORITY_NORMAL 1
 #define DRM_IVPU_CONTEXT_PRIORITY_FOCUS 2
 #define DRM_IVPU_CONTEXT_PRIORITY_REALTIME 3
+#define DRM_IVPU_JOB_PRIORITY_DEFAULT 0
+#define DRM_IVPU_JOB_PRIORITY_IDLE 1
+#define DRM_IVPU_JOB_PRIORITY_NORMAL 2
+#define DRM_IVPU_JOB_PRIORITY_FOCUS 3
+#define DRM_IVPU_JOB_PRIORITY_REALTIME 4
 #define DRM_IVPU_CAP_METRIC_STREAMER 1
 #define DRM_IVPU_CAP_DMA_MEMORY_RANGE 2
 struct drm_ivpu_param {
@@ -80,8 +85,10 @@
   __u32 engine;
   __u32 flags;
   __u32 commands_offset;
+  __u32 priority;
 };
 #define DRM_IVPU_JOB_STATUS_SUCCESS 0
+#define DRM_IVPU_JOB_STATUS_ABORTED 256
 struct drm_ivpu_bo_wait {
   __u32 handle;
   __u32 flags;
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index d180f70..4d83744 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -36,6 +36,7 @@
 #define MSM_PARAM_CMDLINE 0x0d
 #define MSM_PARAM_VA_START 0x0e
 #define MSM_PARAM_VA_SIZE 0x0f
+#define MSM_PARAM_HIGHEST_BANK_BIT 0x10
 #define MSM_PARAM_NR_RINGS MSM_PARAM_PRIORITIES
 struct drm_msm_param {
   __u32 pipe;
@@ -63,6 +64,8 @@
 #define MSM_INFO_GET_NAME 0x03
 #define MSM_INFO_SET_IOVA 0x04
 #define MSM_INFO_GET_FLAGS 0x05
+#define MSM_INFO_SET_METADATA 0x06
+#define MSM_INFO_GET_METADATA 0x07
 struct drm_msm_gem_info {
   __u32 handle;
   __u32 info;
diff --git a/libc/kernel/uapi/drm/nouveau_drm.h b/libc/kernel/uapi/drm/nouveau_drm.h
index 221ff21..f7d870e 100644
--- a/libc/kernel/uapi/drm/nouveau_drm.h
+++ b/libc/kernel/uapi/drm/nouveau_drm.h
@@ -23,6 +23,8 @@
 #define NOUVEAU_GETPARAM_HAS_BO_USAGE 15
 #define NOUVEAU_GETPARAM_HAS_PAGEFLIP 16
 #define NOUVEAU_GETPARAM_EXEC_PUSH_MAX 17
+#define NOUVEAU_GETPARAM_VRAM_BAR_SIZE 18
+#define NOUVEAU_GETPARAM_VRAM_USED 19
 struct drm_nouveau_getparam {
   __u64 param;
   __u64 value;
diff --git a/libc/kernel/uapi/drm/pvr_drm.h b/libc/kernel/uapi/drm/pvr_drm.h
new file mode 100644
index 0000000..c68c719
--- /dev/null
+++ b/libc/kernel/uapi/drm/pvr_drm.h
@@ -0,0 +1,271 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef PVR_DRM_UAPI_H
+#define PVR_DRM_UAPI_H
+#include "drm.h"
+#include <linux/const.h>
+#include <linux/types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct drm_pvr_obj_array {
+  __u32 stride;
+  __u32 count;
+  __u64 array;
+};
+#define DRM_PVR_OBJ_ARRAY(cnt,ptr) {.stride = sizeof((ptr)[0]),.count = (cnt),.array = (__u64) (uintptr_t) (ptr) }
+#define PVR_IOCTL(_ioctl,_mode,_data) _mode(DRM_COMMAND_BASE + (_ioctl), struct drm_pvr_ioctl_ ##_data ##_args)
+#define DRM_IOCTL_PVR_DEV_QUERY PVR_IOCTL(0x00, DRM_IOWR, dev_query)
+#define DRM_IOCTL_PVR_CREATE_BO PVR_IOCTL(0x01, DRM_IOWR, create_bo)
+#define DRM_IOCTL_PVR_GET_BO_MMAP_OFFSET PVR_IOCTL(0x02, DRM_IOWR, get_bo_mmap_offset)
+#define DRM_IOCTL_PVR_CREATE_VM_CONTEXT PVR_IOCTL(0x03, DRM_IOWR, create_vm_context)
+#define DRM_IOCTL_PVR_DESTROY_VM_CONTEXT PVR_IOCTL(0x04, DRM_IOW, destroy_vm_context)
+#define DRM_IOCTL_PVR_VM_MAP PVR_IOCTL(0x05, DRM_IOW, vm_map)
+#define DRM_IOCTL_PVR_VM_UNMAP PVR_IOCTL(0x06, DRM_IOW, vm_unmap)
+#define DRM_IOCTL_PVR_CREATE_CONTEXT PVR_IOCTL(0x07, DRM_IOWR, create_context)
+#define DRM_IOCTL_PVR_DESTROY_CONTEXT PVR_IOCTL(0x08, DRM_IOW, destroy_context)
+#define DRM_IOCTL_PVR_CREATE_FREE_LIST PVR_IOCTL(0x09, DRM_IOWR, create_free_list)
+#define DRM_IOCTL_PVR_DESTROY_FREE_LIST PVR_IOCTL(0x0a, DRM_IOW, destroy_free_list)
+#define DRM_IOCTL_PVR_CREATE_HWRT_DATASET PVR_IOCTL(0x0b, DRM_IOWR, create_hwrt_dataset)
+#define DRM_IOCTL_PVR_DESTROY_HWRT_DATASET PVR_IOCTL(0x0c, DRM_IOW, destroy_hwrt_dataset)
+#define DRM_IOCTL_PVR_SUBMIT_JOBS PVR_IOCTL(0x0d, DRM_IOW, submit_jobs)
+struct drm_pvr_dev_query_gpu_info {
+  __u64 gpu_id;
+  __u32 num_phantoms;
+  __u32 _padding_c;
+};
+struct drm_pvr_dev_query_runtime_info {
+  __u64 free_list_min_pages;
+  __u64 free_list_max_pages;
+  __u32 common_store_alloc_region_size;
+  __u32 common_store_partition_space_size;
+  __u32 max_coeffs;
+  __u32 cdm_max_local_mem_size_regs;
+};
+struct drm_pvr_dev_query_quirks {
+  __u64 quirks;
+  __u16 count;
+  __u16 musthave_count;
+  __u32 _padding_c;
+};
+struct drm_pvr_dev_query_enhancements {
+  __u64 enhancements;
+  __u16 count;
+  __u16 _padding_a;
+  __u32 _padding_c;
+};
+enum drm_pvr_heap_id {
+  DRM_PVR_HEAP_GENERAL = 0,
+  DRM_PVR_HEAP_PDS_CODE_DATA,
+  DRM_PVR_HEAP_USC_CODE,
+  DRM_PVR_HEAP_RGNHDR,
+  DRM_PVR_HEAP_VIS_TEST,
+  DRM_PVR_HEAP_TRANSFER_FRAG,
+  DRM_PVR_HEAP_COUNT
+};
+struct drm_pvr_heap {
+  __u64 base;
+  __u64 size;
+  __u32 flags;
+  __u32 page_size_log2;
+};
+struct drm_pvr_dev_query_heap_info {
+  struct drm_pvr_obj_array heaps;
+};
+enum drm_pvr_static_data_area_usage {
+  DRM_PVR_STATIC_DATA_AREA_EOT = 0,
+  DRM_PVR_STATIC_DATA_AREA_FENCE,
+  DRM_PVR_STATIC_DATA_AREA_VDM_SYNC,
+  DRM_PVR_STATIC_DATA_AREA_YUV_CSC,
+};
+struct drm_pvr_static_data_area {
+  __u16 area_usage;
+  __u16 location_heap_id;
+  __u32 size;
+  __u64 offset;
+};
+struct drm_pvr_dev_query_static_data_areas {
+  struct drm_pvr_obj_array static_data_areas;
+};
+enum drm_pvr_dev_query {
+  DRM_PVR_DEV_QUERY_GPU_INFO_GET = 0,
+  DRM_PVR_DEV_QUERY_RUNTIME_INFO_GET,
+  DRM_PVR_DEV_QUERY_QUIRKS_GET,
+  DRM_PVR_DEV_QUERY_ENHANCEMENTS_GET,
+  DRM_PVR_DEV_QUERY_HEAP_INFO_GET,
+  DRM_PVR_DEV_QUERY_STATIC_DATA_AREAS_GET,
+};
+struct drm_pvr_ioctl_dev_query_args {
+  __u32 type;
+  __u32 size;
+  __u64 pointer;
+};
+#define DRM_PVR_BO_BYPASS_DEVICE_CACHE _BITULL(0)
+#define DRM_PVR_BO_PM_FW_PROTECT _BITULL(1)
+#define DRM_PVR_BO_ALLOW_CPU_USERSPACE_ACCESS _BITULL(2)
+#define DRM_PVR_BO_FLAGS_MASK (DRM_PVR_BO_BYPASS_DEVICE_CACHE | DRM_PVR_BO_PM_FW_PROTECT | DRM_PVR_BO_ALLOW_CPU_USERSPACE_ACCESS)
+struct drm_pvr_ioctl_create_bo_args {
+  __u64 size;
+  __u32 handle;
+  __u32 _padding_c;
+  __u64 flags;
+};
+struct drm_pvr_ioctl_get_bo_mmap_offset_args {
+  __u32 handle;
+  __u32 _padding_4;
+  __u64 offset;
+};
+struct drm_pvr_ioctl_create_vm_context_args {
+  __u32 handle;
+  __u32 _padding_4;
+};
+struct drm_pvr_ioctl_destroy_vm_context_args {
+  __u32 handle;
+  __u32 _padding_4;
+};
+struct drm_pvr_ioctl_vm_map_args {
+  __u32 vm_context_handle;
+  __u32 flags;
+  __u64 device_addr;
+  __u32 handle;
+  __u32 _padding_14;
+  __u64 offset;
+  __u64 size;
+};
+struct drm_pvr_ioctl_vm_unmap_args {
+  __u32 vm_context_handle;
+  __u32 _padding_4;
+  __u64 device_addr;
+  __u64 size;
+};
+enum drm_pvr_ctx_priority {
+  DRM_PVR_CTX_PRIORITY_LOW = - 512,
+  DRM_PVR_CTX_PRIORITY_NORMAL = 0,
+  DRM_PVR_CTX_PRIORITY_HIGH = 512,
+};
+enum drm_pvr_ctx_type {
+  DRM_PVR_CTX_TYPE_RENDER = 0,
+  DRM_PVR_CTX_TYPE_COMPUTE,
+  DRM_PVR_CTX_TYPE_TRANSFER_FRAG,
+};
+struct drm_pvr_ioctl_create_context_args {
+  __u32 type;
+  __u32 flags;
+  __s32 priority;
+  __u32 handle;
+  __u64 static_context_state;
+  __u32 static_context_state_len;
+  __u32 vm_context_handle;
+  __u64 callstack_addr;
+};
+struct drm_pvr_ioctl_destroy_context_args {
+  __u32 handle;
+  __u32 _padding_4;
+};
+struct drm_pvr_ioctl_create_free_list_args {
+  __u64 free_list_gpu_addr;
+  __u32 initial_num_pages;
+  __u32 max_num_pages;
+  __u32 grow_num_pages;
+  __u32 grow_threshold;
+  __u32 vm_context_handle;
+  __u32 handle;
+};
+struct drm_pvr_ioctl_destroy_free_list_args {
+  __u32 handle;
+  __u32 _padding_4;
+};
+struct drm_pvr_create_hwrt_geom_data_args {
+  __u64 tpc_dev_addr;
+  __u32 tpc_size;
+  __u32 tpc_stride;
+  __u64 vheap_table_dev_addr;
+  __u64 rtc_dev_addr;
+};
+struct drm_pvr_create_hwrt_rt_data_args {
+  __u64 pm_mlist_dev_addr;
+  __u64 macrotile_array_dev_addr;
+  __u64 region_header_dev_addr;
+};
+#define PVR_DRM_HWRT_FREE_LIST_LOCAL 0
+#define PVR_DRM_HWRT_FREE_LIST_GLOBAL 1U
+struct drm_pvr_ioctl_create_hwrt_dataset_args {
+  struct drm_pvr_create_hwrt_geom_data_args geom_data_args;
+  struct drm_pvr_create_hwrt_rt_data_args rt_data_args[2];
+  __u32 free_list_handles[2];
+  __u32 width;
+  __u32 height;
+  __u32 samples;
+  __u32 layers;
+  __u32 isp_merge_lower_x;
+  __u32 isp_merge_lower_y;
+  __u32 isp_merge_scale_x;
+  __u32 isp_merge_scale_y;
+  __u32 isp_merge_upper_x;
+  __u32 isp_merge_upper_y;
+  __u32 region_header_size;
+  __u32 handle;
+};
+struct drm_pvr_ioctl_destroy_hwrt_dataset_args {
+  __u32 handle;
+  __u32 _padding_4;
+};
+#define DRM_PVR_SYNC_OP_FLAG_HANDLE_TYPE_MASK 0xf
+#define DRM_PVR_SYNC_OP_FLAG_HANDLE_TYPE_SYNCOBJ 0
+#define DRM_PVR_SYNC_OP_FLAG_HANDLE_TYPE_TIMELINE_SYNCOBJ 1
+#define DRM_PVR_SYNC_OP_FLAG_SIGNAL _BITULL(31)
+#define DRM_PVR_SYNC_OP_FLAG_WAIT 0
+#define DRM_PVR_SYNC_OP_FLAGS_MASK (DRM_PVR_SYNC_OP_FLAG_HANDLE_TYPE_MASK | DRM_PVR_SYNC_OP_FLAG_SIGNAL)
+struct drm_pvr_sync_op {
+  __u32 handle;
+  __u32 flags;
+  __u64 value;
+};
+#define DRM_PVR_SUBMIT_JOB_GEOM_CMD_FIRST _BITULL(0)
+#define DRM_PVR_SUBMIT_JOB_GEOM_CMD_LAST _BITULL(1)
+#define DRM_PVR_SUBMIT_JOB_GEOM_CMD_SINGLE_CORE _BITULL(2)
+#define DRM_PVR_SUBMIT_JOB_GEOM_CMD_FLAGS_MASK (DRM_PVR_SUBMIT_JOB_GEOM_CMD_FIRST | DRM_PVR_SUBMIT_JOB_GEOM_CMD_LAST | DRM_PVR_SUBMIT_JOB_GEOM_CMD_SINGLE_CORE)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_SINGLE_CORE _BITULL(0)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_DEPTHBUFFER _BITULL(1)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_STENCILBUFFER _BITULL(2)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_PREVENT_CDM_OVERLAP _BITULL(3)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_SCRATCHBUFFER _BITULL(4)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_GET_VIS_RESULTS _BITULL(5)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_PARTIAL_RENDER _BITULL(6)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE _BITULL(7)
+#define DRM_PVR_SUBMIT_JOB_FRAG_CMD_FLAGS_MASK (DRM_PVR_SUBMIT_JOB_FRAG_CMD_SINGLE_CORE | DRM_PVR_SUBMIT_JOB_FRAG_CMD_DEPTHBUFFER | DRM_PVR_SUBMIT_JOB_FRAG_CMD_STENCILBUFFER | DRM_PVR_SUBMIT_JOB_FRAG_CMD_PREVENT_CDM_OVERLAP | DRM_PVR_SUBMIT_JOB_FRAG_CMD_SCRATCHBUFFER | DRM_PVR_SUBMIT_JOB_FRAG_CMD_GET_VIS_RESULTS | DRM_PVR_SUBMIT_JOB_FRAG_CMD_PARTIAL_RENDER | DRM_PVR_SUBMIT_JOB_FRAG_CMD_DISABLE_PIXELMERGE)
+#define DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_PREVENT_ALL_OVERLAP _BITULL(0)
+#define DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_SINGLE_CORE _BITULL(1)
+#define DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_FLAGS_MASK (DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_PREVENT_ALL_OVERLAP | DRM_PVR_SUBMIT_JOB_COMPUTE_CMD_SINGLE_CORE)
+#define DRM_PVR_SUBMIT_JOB_TRANSFER_CMD_SINGLE_CORE _BITULL(0)
+#define DRM_PVR_SUBMIT_JOB_TRANSFER_CMD_FLAGS_MASK DRM_PVR_SUBMIT_JOB_TRANSFER_CMD_SINGLE_CORE
+enum drm_pvr_job_type {
+  DRM_PVR_JOB_TYPE_GEOMETRY = 0,
+  DRM_PVR_JOB_TYPE_FRAGMENT,
+  DRM_PVR_JOB_TYPE_COMPUTE,
+  DRM_PVR_JOB_TYPE_TRANSFER_FRAG,
+};
+struct drm_pvr_hwrt_data_ref {
+  __u32 set_handle;
+  __u32 data_index;
+};
+struct drm_pvr_job {
+  __u32 type;
+  __u32 context_handle;
+  __u32 flags;
+  __u32 cmd_stream_len;
+  __u64 cmd_stream;
+  struct drm_pvr_obj_array sync_ops;
+  struct drm_pvr_hwrt_data_ref hwrt;
+};
+struct drm_pvr_ioctl_submit_jobs_args {
+  struct drm_pvr_obj_array jobs;
+};
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/drm/v3d_drm.h b/libc/kernel/uapi/drm/v3d_drm.h
index 594856f..4000fd3 100644
--- a/libc/kernel/uapi/drm/v3d_drm.h
+++ b/libc/kernel/uapi/drm/v3d_drm.h
@@ -21,6 +21,7 @@
 #define DRM_V3D_PERFMON_CREATE 0x08
 #define DRM_V3D_PERFMON_DESTROY 0x09
 #define DRM_V3D_PERFMON_GET_VALUES 0x0a
+#define DRM_V3D_SUBMIT_CPU 0x0b
 #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
 #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
 #define DRM_IOCTL_V3D_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_CREATE_BO, struct drm_v3d_create_bo)
@@ -32,12 +33,19 @@
 #define DRM_IOCTL_V3D_PERFMON_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_CREATE, struct drm_v3d_perfmon_create)
 #define DRM_IOCTL_V3D_PERFMON_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_DESTROY, struct drm_v3d_perfmon_destroy)
 #define DRM_IOCTL_V3D_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_VALUES, struct drm_v3d_perfmon_get_values)
+#define DRM_IOCTL_V3D_SUBMIT_CPU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CPU, struct drm_v3d_submit_cpu)
 #define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01
 #define DRM_V3D_SUBMIT_EXTENSION 0x02
 struct drm_v3d_extension {
   __u64 next;
   __u32 id;
 #define DRM_V3D_EXT_ID_MULTI_SYNC 0x01
+#define DRM_V3D_EXT_ID_CPU_INDIRECT_CSD 0x02
+#define DRM_V3D_EXT_ID_CPU_TIMESTAMP_QUERY 0x03
+#define DRM_V3D_EXT_ID_CPU_RESET_TIMESTAMP_QUERY 0x04
+#define DRM_V3D_EXT_ID_CPU_COPY_TIMESTAMP_QUERY 0x05
+#define DRM_V3D_EXT_ID_CPU_RESET_PERFORMANCE_QUERY 0x06
+#define DRM_V3D_EXT_ID_CPU_COPY_PERFORMANCE_QUERY 0x07
   __u32 flags;
 };
 struct drm_v3d_sem {
@@ -52,6 +60,7 @@
   V3D_TFU,
   V3D_CSD,
   V3D_CACHE_CLEAN,
+  V3D_CPU,
 };
 struct drm_v3d_multi_sync {
   struct drm_v3d_extension base;
@@ -109,6 +118,7 @@
   DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH,
   DRM_V3D_PARAM_SUPPORTS_PERFMON,
   DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT,
+  DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE,
 };
 struct drm_v3d_get_param {
   __u32 param;
@@ -133,6 +143,10 @@
   __u32 out_sync;
   __u32 flags;
   __u64 extensions;
+  struct {
+    __u32 ioc;
+    __u32 pad;
+  } v71;
 };
 struct drm_v3d_submit_csd {
   __u32 cfg[7];
@@ -146,6 +160,66 @@
   __u32 flags;
   __u32 pad;
 };
+struct drm_v3d_indirect_csd {
+  struct drm_v3d_extension base;
+  struct drm_v3d_submit_csd submit;
+  __u32 indirect;
+  __u32 offset;
+  __u32 wg_size;
+  __u32 wg_uniform_offsets[3];
+};
+struct drm_v3d_timestamp_query {
+  struct drm_v3d_extension base;
+  __u64 offsets;
+  __u64 syncs;
+  __u32 count;
+  __u32 pad;
+};
+struct drm_v3d_reset_timestamp_query {
+  struct drm_v3d_extension base;
+  __u64 syncs;
+  __u32 offset;
+  __u32 count;
+};
+struct drm_v3d_copy_timestamp_query {
+  struct drm_v3d_extension base;
+  __u8 do_64bit;
+  __u8 do_partial;
+  __u8 availability_bit;
+  __u8 pad;
+  __u32 offset;
+  __u32 stride;
+  __u32 count;
+  __u64 offsets;
+  __u64 syncs;
+};
+struct drm_v3d_reset_performance_query {
+  struct drm_v3d_extension base;
+  __u64 syncs;
+  __u32 count;
+  __u32 nperfmons;
+  __u64 kperfmon_ids;
+};
+struct drm_v3d_copy_performance_query {
+  struct drm_v3d_extension base;
+  __u8 do_64bit;
+  __u8 do_partial;
+  __u8 availability_bit;
+  __u8 pad;
+  __u32 offset;
+  __u32 stride;
+  __u32 nperfmons;
+  __u32 ncounters;
+  __u32 count;
+  __u64 syncs;
+  __u64 kperfmon_ids;
+};
+struct drm_v3d_submit_cpu {
+  __u64 bo_handles;
+  __u32 bo_handle_count;
+  __u32 flags;
+  __u64 extensions;
+};
 enum {
   V3D_PERFCNT_FEP_VALID_PRIMTS_NO_PIXELS,
   V3D_PERFCNT_FEP_VALID_PRIMS,
diff --git a/libc/kernel/uapi/drm/virtgpu_drm.h b/libc/kernel/uapi/drm/virtgpu_drm.h
index 6babe2d..d79c7d9 100644
--- a/libc/kernel/uapi/drm/virtgpu_drm.h
+++ b/libc/kernel/uapi/drm/virtgpu_drm.h
@@ -58,6 +58,7 @@
 #define VIRTGPU_PARAM_CROSS_DEVICE 5
 #define VIRTGPU_PARAM_CONTEXT_INIT 6
 #define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7
+#define VIRTGPU_PARAM_EXPLICIT_DEBUG_NAME 8
 struct drm_virtgpu_getparam {
   __u64 param;
   __u64 value;
@@ -140,6 +141,7 @@
 #define VIRTGPU_CONTEXT_PARAM_CAPSET_ID 0x0001
 #define VIRTGPU_CONTEXT_PARAM_NUM_RINGS 0x0002
 #define VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK 0x0003
+#define VIRTGPU_CONTEXT_PARAM_DEBUG_NAME 0x0004
 struct drm_virtgpu_context_set_param {
   __u64 param;
   __u64 value;
diff --git a/libc/kernel/uapi/drm/xe_drm.h b/libc/kernel/uapi/drm/xe_drm.h
new file mode 100644
index 0000000..1e9f128
--- /dev/null
+++ b/libc/kernel/uapi/drm/xe_drm.h
@@ -0,0 +1,296 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_XE_DRM_H_
+#define _UAPI_XE_DRM_H_
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define DRM_XE_DEVICE_QUERY 0x00
+#define DRM_XE_GEM_CREATE 0x01
+#define DRM_XE_GEM_MMAP_OFFSET 0x02
+#define DRM_XE_VM_CREATE 0x03
+#define DRM_XE_VM_DESTROY 0x04
+#define DRM_XE_VM_BIND 0x05
+#define DRM_XE_EXEC_QUEUE_CREATE 0x06
+#define DRM_XE_EXEC_QUEUE_DESTROY 0x07
+#define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x08
+#define DRM_XE_EXEC 0x09
+#define DRM_XE_WAIT_USER_FENCE 0x0a
+#define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query)
+#define DRM_IOCTL_XE_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_GEM_CREATE, struct drm_xe_gem_create)
+#define DRM_IOCTL_XE_GEM_MMAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_GEM_MMAP_OFFSET, struct drm_xe_gem_mmap_offset)
+#define DRM_IOCTL_XE_VM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_VM_CREATE, struct drm_xe_vm_create)
+#define DRM_IOCTL_XE_VM_DESTROY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_VM_DESTROY, struct drm_xe_vm_destroy)
+#define DRM_IOCTL_XE_VM_BIND DRM_IOW(DRM_COMMAND_BASE + DRM_XE_VM_BIND, struct drm_xe_vm_bind)
+#define DRM_IOCTL_XE_EXEC_QUEUE_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_CREATE, struct drm_xe_exec_queue_create)
+#define DRM_IOCTL_XE_EXEC_QUEUE_DESTROY DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_DESTROY, struct drm_xe_exec_queue_destroy)
+#define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_GET_PROPERTY, struct drm_xe_exec_queue_get_property)
+#define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec)
+#define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence)
+struct drm_xe_user_extension {
+  __u64 next_extension;
+  __u32 name;
+  __u32 pad;
+};
+struct drm_xe_ext_set_property {
+  struct drm_xe_user_extension base;
+  __u32 property;
+  __u32 pad;
+  __u64 value;
+  __u64 reserved[2];
+};
+struct drm_xe_engine_class_instance {
+#define DRM_XE_ENGINE_CLASS_RENDER 0
+#define DRM_XE_ENGINE_CLASS_COPY 1
+#define DRM_XE_ENGINE_CLASS_VIDEO_DECODE 2
+#define DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE 3
+#define DRM_XE_ENGINE_CLASS_COMPUTE 4
+#define DRM_XE_ENGINE_CLASS_VM_BIND 5
+  __u16 engine_class;
+  __u16 engine_instance;
+  __u16 gt_id;
+  __u16 pad;
+};
+struct drm_xe_engine {
+  struct drm_xe_engine_class_instance instance;
+  __u64 reserved[3];
+};
+struct drm_xe_query_engines {
+  __u32 num_engines;
+  __u32 pad;
+  struct drm_xe_engine engines[];
+};
+enum drm_xe_memory_class {
+  DRM_XE_MEM_REGION_CLASS_SYSMEM = 0,
+  DRM_XE_MEM_REGION_CLASS_VRAM
+};
+struct drm_xe_mem_region {
+  __u16 mem_class;
+  __u16 instance;
+  __u32 min_page_size;
+  __u64 total_size;
+  __u64 used;
+  __u64 cpu_visible_size;
+  __u64 cpu_visible_used;
+  __u64 reserved[6];
+};
+struct drm_xe_query_mem_regions {
+  __u32 num_mem_regions;
+  __u32 pad;
+  struct drm_xe_mem_region mem_regions[];
+};
+struct drm_xe_query_config {
+  __u32 num_params;
+  __u32 pad;
+#define DRM_XE_QUERY_CONFIG_REV_AND_DEVICE_ID 0
+#define DRM_XE_QUERY_CONFIG_FLAGS 1
+#define DRM_XE_QUERY_CONFIG_FLAG_HAS_VRAM (1 << 0)
+#define DRM_XE_QUERY_CONFIG_MIN_ALIGNMENT 2
+#define DRM_XE_QUERY_CONFIG_VA_BITS 3
+#define DRM_XE_QUERY_CONFIG_MAX_EXEC_QUEUE_PRIORITY 4
+  __u64 info[];
+};
+struct drm_xe_gt {
+#define DRM_XE_QUERY_GT_TYPE_MAIN 0
+#define DRM_XE_QUERY_GT_TYPE_MEDIA 1
+  __u16 type;
+  __u16 tile_id;
+  __u16 gt_id;
+  __u16 pad[3];
+  __u32 reference_clock;
+  __u64 near_mem_regions;
+  __u64 far_mem_regions;
+  __u64 reserved[8];
+};
+struct drm_xe_query_gt_list {
+  __u32 num_gt;
+  __u32 pad;
+  struct drm_xe_gt gt_list[];
+};
+struct drm_xe_query_topology_mask {
+  __u16 gt_id;
+#define DRM_XE_TOPO_DSS_GEOMETRY (1 << 0)
+#define DRM_XE_TOPO_DSS_COMPUTE (1 << 1)
+#define DRM_XE_TOPO_EU_PER_DSS (1 << 2)
+  __u16 type;
+  __u32 num_bytes;
+  __u8 mask[];
+};
+struct drm_xe_query_engine_cycles {
+  struct drm_xe_engine_class_instance eci;
+  __s32 clockid;
+  __u32 width;
+  __u64 engine_cycles;
+  __u64 cpu_timestamp;
+  __u64 cpu_delta;
+};
+struct drm_xe_device_query {
+  __u64 extensions;
+#define DRM_XE_DEVICE_QUERY_ENGINES 0
+#define DRM_XE_DEVICE_QUERY_MEM_REGIONS 1
+#define DRM_XE_DEVICE_QUERY_CONFIG 2
+#define DRM_XE_DEVICE_QUERY_GT_LIST 3
+#define DRM_XE_DEVICE_QUERY_HWCONFIG 4
+#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
+#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
+  __u32 query;
+  __u32 size;
+  __u64 data;
+  __u64 reserved[2];
+};
+struct drm_xe_gem_create {
+  __u64 extensions;
+  __u64 size;
+  __u32 placement;
+#define DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING (1 << 0)
+#define DRM_XE_GEM_CREATE_FLAG_SCANOUT (1 << 1)
+#define DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM (1 << 2)
+  __u32 flags;
+  __u32 vm_id;
+  __u32 handle;
+#define DRM_XE_GEM_CPU_CACHING_WB 1
+#define DRM_XE_GEM_CPU_CACHING_WC 2
+  __u16 cpu_caching;
+  __u16 pad[3];
+  __u64 reserved[2];
+};
+struct drm_xe_gem_mmap_offset {
+  __u64 extensions;
+  __u32 handle;
+  __u32 flags;
+  __u64 offset;
+  __u64 reserved[2];
+};
+struct drm_xe_vm_create {
+  __u64 extensions;
+#define DRM_XE_VM_CREATE_FLAG_SCRATCH_PAGE (1 << 0)
+#define DRM_XE_VM_CREATE_FLAG_LR_MODE (1 << 1)
+#define DRM_XE_VM_CREATE_FLAG_FAULT_MODE (1 << 2)
+  __u32 flags;
+  __u32 vm_id;
+  __u64 reserved[2];
+};
+struct drm_xe_vm_destroy {
+  __u32 vm_id;
+  __u32 pad;
+  __u64 reserved[2];
+};
+struct drm_xe_vm_bind_op {
+  __u64 extensions;
+  __u32 obj;
+  __u16 pat_index;
+  __u16 pad;
+  union {
+    __u64 obj_offset;
+    __u64 userptr;
+  };
+  __u64 range;
+  __u64 addr;
+#define DRM_XE_VM_BIND_OP_MAP 0x0
+#define DRM_XE_VM_BIND_OP_UNMAP 0x1
+#define DRM_XE_VM_BIND_OP_MAP_USERPTR 0x2
+#define DRM_XE_VM_BIND_OP_UNMAP_ALL 0x3
+#define DRM_XE_VM_BIND_OP_PREFETCH 0x4
+  __u32 op;
+#define DRM_XE_VM_BIND_FLAG_NULL (1 << 2)
+#define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3)
+  __u32 flags;
+  __u32 prefetch_mem_region_instance;
+  __u32 pad2;
+  __u64 reserved[3];
+};
+struct drm_xe_vm_bind {
+  __u64 extensions;
+  __u32 vm_id;
+  __u32 exec_queue_id;
+  __u32 pad;
+  __u32 num_binds;
+  union {
+    struct drm_xe_vm_bind_op bind;
+    __u64 vector_of_binds;
+  };
+  __u32 pad2;
+  __u32 num_syncs;
+  __u64 syncs;
+  __u64 reserved[2];
+};
+struct drm_xe_exec_queue_create {
+#define DRM_XE_EXEC_QUEUE_EXTENSION_SET_PROPERTY 0
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_PRIORITY 0
+#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_TIMESLICE 1
+  __u64 extensions;
+  __u16 width;
+  __u16 num_placements;
+  __u32 vm_id;
+  __u32 flags;
+  __u32 exec_queue_id;
+  __u64 instances;
+  __u64 reserved[2];
+};
+struct drm_xe_exec_queue_destroy {
+  __u32 exec_queue_id;
+  __u32 pad;
+  __u64 reserved[2];
+};
+struct drm_xe_exec_queue_get_property {
+  __u64 extensions;
+  __u32 exec_queue_id;
+#define DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN 0
+  __u32 property;
+  __u64 value;
+  __u64 reserved[2];
+};
+struct drm_xe_sync {
+  __u64 extensions;
+#define DRM_XE_SYNC_TYPE_SYNCOBJ 0x0
+#define DRM_XE_SYNC_TYPE_TIMELINE_SYNCOBJ 0x1
+#define DRM_XE_SYNC_TYPE_USER_FENCE 0x2
+  __u32 type;
+#define DRM_XE_SYNC_FLAG_SIGNAL (1 << 0)
+  __u32 flags;
+  union {
+    __u32 handle;
+    __u64 addr;
+  };
+  __u64 timeline_value;
+  __u64 reserved[2];
+};
+struct drm_xe_exec {
+  __u64 extensions;
+  __u32 exec_queue_id;
+  __u32 num_syncs;
+  __u64 syncs;
+  __u64 address;
+  __u16 num_batch_buffer;
+  __u16 pad[3];
+  __u64 reserved[2];
+};
+struct drm_xe_wait_user_fence {
+  __u64 extensions;
+  __u64 addr;
+#define DRM_XE_UFENCE_WAIT_OP_EQ 0x0
+#define DRM_XE_UFENCE_WAIT_OP_NEQ 0x1
+#define DRM_XE_UFENCE_WAIT_OP_GT 0x2
+#define DRM_XE_UFENCE_WAIT_OP_GTE 0x3
+#define DRM_XE_UFENCE_WAIT_OP_LT 0x4
+#define DRM_XE_UFENCE_WAIT_OP_LTE 0x5
+  __u16 op;
+#define DRM_XE_UFENCE_WAIT_FLAG_ABSTIME (1 << 0)
+  __u16 flags;
+  __u32 pad;
+  __u64 value;
+  __u64 mask;
+  __s64 timeout;
+  __u32 exec_queue_id;
+  __u32 pad2;
+  __u64 reserved[2];
+};
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 1abb3a3..6e64ebc 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -120,20 +120,22 @@
   __u32 command;
   __s32 param;
 };
-#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
-#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64)
-#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32)
-#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32)
-#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
-#define BINDER_THREAD_EXIT _IOW('b', 8, __s32)
-#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
-#define BINDER_GET_NODE_DEBUG_INFO _IOWR('b', 11, struct binder_node_debug_info)
-#define BINDER_GET_NODE_INFO_FOR_REF _IOWR('b', 12, struct binder_node_info_for_ref)
-#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object)
-#define BINDER_FREEZE _IOW('b', 14, struct binder_freeze_info)
-#define BINDER_GET_FROZEN_INFO _IOWR('b', 15, struct binder_frozen_status_info)
-#define BINDER_ENABLE_ONEWAY_SPAM_DETECTION _IOW('b', 16, __u32)
-#define BINDER_GET_EXTENDED_ERROR _IOWR('b', 17, struct binder_extended_error)
+enum {
+  BINDER_WRITE_READ = _IOWR('b', 1, struct binder_write_read),
+  BINDER_SET_IDLE_TIMEOUT = _IOW('b', 3, __s64),
+  BINDER_SET_MAX_THREADS = _IOW('b', 5, __u32),
+  BINDER_SET_IDLE_PRIORITY = _IOW('b', 6, __s32),
+  BINDER_SET_CONTEXT_MGR = _IOW('b', 7, __s32),
+  BINDER_THREAD_EXIT = _IOW('b', 8, __s32),
+  BINDER_VERSION = _IOWR('b', 9, struct binder_version),
+  BINDER_GET_NODE_DEBUG_INFO = _IOWR('b', 11, struct binder_node_debug_info),
+  BINDER_GET_NODE_INFO_FOR_REF = _IOWR('b', 12, struct binder_node_info_for_ref),
+  BINDER_SET_CONTEXT_MGR_EXT = _IOW('b', 13, struct flat_binder_object),
+  BINDER_FREEZE = _IOW('b', 14, struct binder_freeze_info),
+  BINDER_GET_FROZEN_INFO = _IOWR('b', 15, struct binder_frozen_status_info),
+  BINDER_ENABLE_ONEWAY_SPAM_DETECTION = _IOW('b', 16, __u32),
+  BINDER_GET_EXTENDED_ERROR = _IOWR('b', 17, struct binder_extended_error),
+};
 enum transaction_flags {
   TF_ONE_WAY = 0x01,
   TF_ROOT_OBJECT = 0x04,
diff --git a/libc/kernel/uapi/linux/batadv_packet.h b/libc/kernel/uapi/linux/batadv_packet.h
index eb72d63..83e5e71 100644
--- a/libc/kernel/uapi/linux/batadv_packet.h
+++ b/libc/kernel/uapi/linux/batadv_packet.h
@@ -51,6 +51,7 @@
   BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2,
   BATADV_MCAST_WANT_NO_RTR4 = 1UL << 3,
   BATADV_MCAST_WANT_NO_RTR6 = 1UL << 4,
+  BATADV_MCAST_HAVE_MC_PTYPE_CAPA = 1UL << 5,
 };
 #define BATADV_TT_DATA_TYPE_MASK 0x0F
 enum batadv_tt_data_flags {
@@ -76,6 +77,7 @@
   BATADV_TVLV_TT = 0x04,
   BATADV_TVLV_ROAM = 0x05,
   BATADV_TVLV_MCAST = 0x06,
+  BATADV_TVLV_MCAST_TRACKER = 0x07,
 };
 #pragma pack(2)
 struct batadv_bla_claim_dst {
@@ -208,6 +210,13 @@
   __be32 seqno;
   __u8 orig[ETH_ALEN];
 };
+struct batadv_mcast_packet {
+  __u8 packet_type;
+  __u8 version;
+  __u8 ttl;
+  __u8 reserved;
+  __be16 tvlv_len;
+};
 struct batadv_coded_packet {
   __u8 packet_type;
   __u8 version;
@@ -267,5 +276,8 @@
   __u8 flags;
   __u8 reserved[3];
 };
+struct batadv_tvlv_mcast_tracker {
+  __be16 num_dests;
+};
 #pragma pack()
 #endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 25e8ad7..8f82b71 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -271,8 +271,9 @@
   BPF_LINK_TYPE_TCX = 11,
   BPF_LINK_TYPE_UPROBE_MULTI = 12,
   BPF_LINK_TYPE_NETKIT = 13,
-  MAX_BPF_LINK_TYPE,
+  __MAX_BPF_LINK_TYPE,
 };
+#define MAX_BPF_LINK_TYPE __MAX_BPF_LINK_TYPE
 enum bpf_perf_event_type {
   BPF_PERF_EVENT_UNSPEC = 0,
   BPF_PERF_EVENT_UPROBE = 1,
@@ -296,6 +297,7 @@
 #define BPF_F_SLEEPABLE (1U << 4)
 #define BPF_F_XDP_HAS_FRAGS (1U << 5)
 #define BPF_F_XDP_DEV_BOUND_ONLY (1U << 6)
+#define BPF_F_TEST_REG_INVARIANTS (1U << 7)
 enum {
   BPF_F_KPROBE_MULTI_RETURN = (1U << 0)
 };
@@ -1063,6 +1065,16 @@
       __u64 missed;
     } kprobe_multi;
     struct {
+      __aligned_u64 path;
+      __aligned_u64 offsets;
+      __aligned_u64 ref_ctr_offsets;
+      __aligned_u64 cookies;
+      __u32 path_size;
+      __u32 count;
+      __u32 flags;
+      __u32 pid;
+    } uprobe_multi;
+    struct {
       __u32 type;
       __u32 : 32;
       union {
@@ -1198,6 +1210,7 @@
   BPF_TCP_LISTEN,
   BPF_TCP_CLOSING,
   BPF_TCP_NEW_SYN_RECV,
+  BPF_TCP_BOUND_INACTIVE,
   BPF_TCP_MAX_STATES
 };
 enum {
@@ -1358,34 +1371,25 @@
   __u32 val;
 };
 struct bpf_timer {
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[2];
 } __attribute__((aligned(8)));
 struct bpf_dynptr {
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[2];
 } __attribute__((aligned(8)));
 struct bpf_list_head {
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[2];
 } __attribute__((aligned(8)));
 struct bpf_list_node {
-  __u64 : 64;
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[3];
 } __attribute__((aligned(8)));
 struct bpf_rb_root {
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[2];
 } __attribute__((aligned(8)));
 struct bpf_rb_node {
-  __u64 : 64;
-  __u64 : 64;
-  __u64 : 64;
-  __u64 : 64;
+  __u64 __opaque[4];
 } __attribute__((aligned(8)));
 struct bpf_refcount {
-  __u32 : 32;
+  __u32 __opaque[1];
 } __attribute__((aligned(4)));
 struct bpf_sysctl {
   __u32 write;
diff --git a/libc/kernel/uapi/linux/bpfilter.h b/libc/kernel/uapi/linux/bpfilter.h
deleted file mode 100644
index a0833a3..0000000
--- a/libc/kernel/uapi/linux/bpfilter.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is auto-generated. Modifications will be lost.
- *
- * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
- * for more information.
- */
-#ifndef _UAPI_LINUX_BPFILTER_H
-#define _UAPI_LINUX_BPFILTER_H
-#include <linux/if.h>
-enum {
-  BPFILTER_IPT_SO_SET_REPLACE = 64,
-  BPFILTER_IPT_SO_SET_ADD_COUNTERS = 65,
-  BPFILTER_IPT_SET_MAX,
-};
-enum {
-  BPFILTER_IPT_SO_GET_INFO = 64,
-  BPFILTER_IPT_SO_GET_ENTRIES = 65,
-  BPFILTER_IPT_SO_GET_REVISION_MATCH = 66,
-  BPFILTER_IPT_SO_GET_REVISION_TARGET = 67,
-  BPFILTER_IPT_GET_MAX,
-};
-#endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 27564f8..5d449f8 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -310,6 +310,7 @@
 };
 #define BTRFS_DEFRAG_RANGE_COMPRESS 1
 #define BTRFS_DEFRAG_RANGE_START_IO 2
+#define BTRFS_DEFRAG_RANGE_FLAGS_SUPP (BTRFS_DEFRAG_RANGE_COMPRESS | BTRFS_DEFRAG_RANGE_START_IO)
 struct btrfs_ioctl_defrag_range_args {
   __u64 start;
   __u64 len;
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index a008826..942e817 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #define CXL_MEM_QUERY_COMMANDS _IOR(0xCE, 1, struct cxl_mem_query_commands)
 #define CXL_MEM_SEND_COMMAND _IOWR(0xCE, 2, struct cxl_send_command)
-#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___DEPRECATED(GET_POISON, "Get Poison List"), ___DEPRECATED(INJECT_POISON, "Inject Poison"), ___DEPRECATED(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___DEPRECATED(SCAN_MEDIA, "Scan Media"), ___DEPRECATED(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(MAX, "invalid / last command")
+#define CXL_CMDS ___C(INVALID, "Invalid Command"), ___C(IDENTIFY, "Identify Command"), ___C(RAW, "Raw device command"), ___C(GET_SUPPORTED_LOGS, "Get Supported Logs"), ___C(GET_FW_INFO, "Get FW Info"), ___C(GET_PARTITION_INFO, "Get Partition Information"), ___C(GET_LSA, "Get Label Storage Area"), ___C(GET_HEALTH_INFO, "Get Health Info"), ___C(GET_LOG, "Get Log"), ___C(SET_PARTITION_INFO, "Set Partition Information"), ___C(SET_LSA, "Set Label Storage Area"), ___C(GET_ALERT_CONFIG, "Get Alert Configuration"), ___C(SET_ALERT_CONFIG, "Set Alert Configuration"), ___C(GET_SHUTDOWN_STATE, "Get Shutdown State"), ___C(SET_SHUTDOWN_STATE, "Set Shutdown State"), ___DEPRECATED(GET_POISON, "Get Poison List"), ___DEPRECATED(INJECT_POISON, "Inject Poison"), ___DEPRECATED(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___DEPRECATED(SCAN_MEDIA, "Scan Media"), ___DEPRECATED(GET_SCAN_MEDIA, "Get Scan Media Results"), ___C(GET_TIMESTAMP, "Get Timestamp"), ___C(MAX, "invalid / last command")
 #define ___C(a,b) CXL_MEM_COMMAND_ID_ ##a
 #define ___DEPRECATED(a,b) CXL_MEM_DEPRECATED_ID_ ##a
 enum {
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index bc44a70..968d6be 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -97,6 +97,7 @@
   DEVLINK_CMD_LINECARD_DEL,
   DEVLINK_CMD_SELFTESTS_GET,
   DEVLINK_CMD_SELFTESTS_RUN,
+  DEVLINK_CMD_NOTIFY_FILTER_SET,
   __DEVLINK_CMD_MAX,
   DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/dpll.h b/libc/kernel/uapi/linux/dpll.h
index 9b5f37d..cbefd15 100644
--- a/libc/kernel/uapi/linux/dpll.h
+++ b/libc/kernel/uapi/linux/dpll.h
@@ -98,6 +98,7 @@
   DPLL_A_PIN_PHASE_ADJUST_MAX,
   DPLL_A_PIN_PHASE_ADJUST,
   DPLL_A_PIN_PHASE_OFFSET,
+  DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
   __DPLL_A_PIN_MAX,
   DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
 };
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 0d166af..e3466cf 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -433,7 +433,8 @@
   __u32 indir_size;
   __u32 key_size;
   __u8 hfunc;
-  __u8 rsvd8[3];
+  __u8 input_xfrm;
+  __u8 rsvd8[2];
   __u32 rsvd32;
   __u32 rss_config[];
 };
@@ -857,6 +858,8 @@
 #define WAKE_MAGICSECURE (1 << 6)
 #define WAKE_FILTER (1 << 7)
 #define WOL_MODE_COUNT 8
+#define RXH_XFRM_SYM_XOR (1 << 0)
+#define RXH_XFRM_NO_CHANGE 0xff
 #define TCP_V4_FLOW 0x01
 #define UDP_V4_FLOW 0x02
 #define SCTP_V4_FLOW 0x03
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index c5012d2..e4fc40e 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -638,6 +638,7 @@
   ETHTOOL_A_RSS_HFUNC,
   ETHTOOL_A_RSS_INDIR,
   ETHTOOL_A_RSS_HKEY,
+  ETHTOOL_A_RSS_INPUT_XFRM,
   __ETHTOOL_A_RSS_CNT,
   ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1),
 };
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 9288653..f1a8eac 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -192,6 +192,7 @@
 #define PAGE_IS_SWAPPED (1 << 4)
 #define PAGE_IS_PFNZERO (1 << 5)
 #define PAGE_IS_HUGE (1 << 6)
+#define PAGE_IS_SOFT_DIRTY (1 << 7)
 struct page_region {
   __u64 start;
   __u64 end;
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index a738876..97c0fb6 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -587,6 +587,7 @@
   MDBE_ATTR_VNI,
   MDBE_ATTR_IFINDEX,
   MDBE_ATTR_SRC_VNI,
+  MDBE_ATTR_STATE_MASK,
   __MDBE_ATTR_MAX,
 };
 #define MDBE_ATTR_MAX (__MDBE_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 54b751e..19bbfa1 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -536,6 +536,7 @@
   IFLA_VXLAN_DF,
   IFLA_VXLAN_VNIFILTER,
   IFLA_VXLAN_LOCALBYPASS,
+  IFLA_VXLAN_LABEL_POLICY,
   __IFLA_VXLAN_MAX
 };
 #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
@@ -550,6 +551,12 @@
   __VXLAN_DF_END,
   VXLAN_DF_MAX = __VXLAN_DF_END - 1,
 };
+enum ifla_vxlan_label_policy {
+  VXLAN_LABEL_FIXED = 0,
+  VXLAN_LABEL_INHERIT = 1,
+  __VXLAN_LABEL_END,
+  VXLAN_LABEL_MAX = __VXLAN_LABEL_END - 1,
+};
 enum {
   IFLA_GENEVE_UNSPEC,
   IFLA_GENEVE_ID,
diff --git a/libc/kernel/uapi/linux/if_xdp.h b/libc/kernel/uapi/linux/if_xdp.h
index 02a014a..b7eec87 100644
--- a/libc/kernel/uapi/linux/if_xdp.h
+++ b/libc/kernel/uapi/linux/if_xdp.h
@@ -13,6 +13,7 @@
 #define XDP_USE_NEED_WAKEUP (1 << 3)
 #define XDP_USE_SG (1 << 4)
 #define XDP_UMEM_UNALIGNED_CHUNK_FLAG (1 << 0)
+#define XDP_UMEM_TX_SW_CSUM (1 << 1)
 struct sockaddr_xdp {
   __u16 sxdp_family;
   __u16 sxdp_flags;
@@ -47,6 +48,7 @@
   __u32 chunk_size;
   __u32 headroom;
   __u32 flags;
+  __u32 tx_metadata_len;
 };
 struct xdp_statistics {
   __u64 rx_dropped;
@@ -66,10 +68,25 @@
 #define XDP_UMEM_PGOFF_COMPLETION_RING 0x180000000ULL
 #define XSK_UNALIGNED_BUF_OFFSET_SHIFT 48
 #define XSK_UNALIGNED_BUF_ADDR_MASK ((1ULL << XSK_UNALIGNED_BUF_OFFSET_SHIFT) - 1)
+#define XDP_TXMD_FLAGS_TIMESTAMP (1 << 0)
+#define XDP_TXMD_FLAGS_CHECKSUM (1 << 1)
+struct xsk_tx_metadata {
+  __u64 flags;
+  union {
+    struct {
+      __u16 csum_start;
+      __u16 csum_offset;
+    } request;
+    struct {
+      __u64 tx_timestamp;
+    } completion;
+  };
+};
 struct xdp_desc {
   __u64 addr;
   __u32 len;
   __u32 options;
 };
 #define XDP_PKT_CONTD (1 << 0)
+#define XDP_TX_METADATA (1 << 1)
 #endif
diff --git a/libc/kernel/uapi/linux/iio/types.h b/libc/kernel/uapi/linux/iio/types.h
index 4e4324a..f40cb95 100644
--- a/libc/kernel/uapi/linux/iio/types.h
+++ b/libc/kernel/uapi/linux/iio/types.h
@@ -99,6 +99,8 @@
   IIO_MOD_PITCH,
   IIO_MOD_YAW,
   IIO_MOD_ROLL,
+  IIO_MOD_LIGHT_UVA,
+  IIO_MOD_LIGHT_UVB,
 };
 enum iio_event_type {
   IIO_EV_TYPE_THRESH,
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 57c6405..27675d5 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -58,6 +58,7 @@
     __u32 uring_cmd_flags;
     __u32 waitid_flags;
     __u32 futex_flags;
+    __u32 install_fd_flags;
   };
   __u64 user_data;
   union {
@@ -172,6 +173,7 @@
   IORING_OP_FUTEX_WAIT,
   IORING_OP_FUTEX_WAKE,
   IORING_OP_FUTEX_WAITV,
+  IORING_OP_FIXED_FD_INSTALL,
   IORING_OP_LAST,
 };
 #define IORING_URING_CMD_FIXED (1U << 0)
@@ -209,6 +211,7 @@
 };
 #define IORING_MSG_RING_CQE_SKIP (1U << 0)
 #define IORING_MSG_RING_FLAGS_PASS (1U << 1)
+#define IORING_FIXED_FD_NO_CLOEXEC (1U << 0)
 struct io_uring_cqe {
   __u64 user_data;
   __s32 res;
@@ -312,6 +315,7 @@
   IORING_UNREGISTER_PBUF_RING = 23,
   IORING_REGISTER_SYNC_CANCEL = 24,
   IORING_REGISTER_FILE_ALLOC_RANGE = 25,
+  IORING_REGISTER_PBUF_STATUS = 26,
   IORING_REGISTER_LAST,
   IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
 };
@@ -397,6 +401,11 @@
   __u16 flags;
   __u64 resv[3];
 };
+struct io_uring_buf_status {
+  __u32 buf_group;
+  __u32 head;
+  __u32 resv[8];
+};
 enum {
   IORING_RESTRICTION_REGISTER_OP = 0,
   IORING_RESTRICTION_SQE_OP = 1,
diff --git a/libc/kernel/uapi/linux/iommufd.h b/libc/kernel/uapi/linux/iommufd.h
index d19a471..2570628 100644
--- a/libc/kernel/uapi/linux/iommufd.h
+++ b/libc/kernel/uapi/linux/iommufd.h
@@ -24,6 +24,7 @@
   IOMMUFD_CMD_GET_HW_INFO,
   IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING,
   IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP,
+  IOMMUFD_CMD_HWPT_INVALIDATE,
 };
 struct iommu_destroy {
   __u32 size;
@@ -200,4 +201,26 @@
   __aligned_u64 data;
 };
 #define IOMMU_HWPT_GET_DIRTY_BITMAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP)
+enum iommu_hwpt_invalidate_data_type {
+  IOMMU_HWPT_INVALIDATE_DATA_VTD_S1,
+};
+enum iommu_hwpt_vtd_s1_invalidate_flags {
+  IOMMU_VTD_INV_FLAGS_LEAF = 1 << 0,
+};
+struct iommu_hwpt_vtd_s1_invalidate {
+  __aligned_u64 addr;
+  __aligned_u64 npages;
+  __u32 flags;
+  __u32 __reserved;
+};
+struct iommu_hwpt_invalidate {
+  __u32 size;
+  __u32 hwpt_id;
+  __aligned_u64 data_uptr;
+  __u32 data_type;
+  __u32 entry_len;
+  __u32 entry_num;
+  __u32 __reserved;
+};
+#define IOMMU_HWPT_INVALIDATE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_INVALIDATE)
 #endif
diff --git a/libc/kernel/uapi/linux/kexec.h b/libc/kernel/uapi/linux/kexec.h
index 53c86f3..c5c8623 100644
--- a/libc/kernel/uapi/linux/kexec.h
+++ b/libc/kernel/uapi/linux/kexec.h
@@ -14,6 +14,7 @@
 #define KEXEC_FILE_UNLOAD 0x00000001
 #define KEXEC_FILE_ON_CRASH 0x00000002
 #define KEXEC_FILE_NO_INITRAMFS 0x00000004
+#define KEXEC_FILE_DEBUG 0x00000008
 #define KEXEC_ARCH_DEFAULT (0 << 16)
 #define KEXEC_ARCH_386 (3 << 16)
 #define KEXEC_ARCH_68K (4 << 16)
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 2a89638..ea4f769 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -12,59 +12,6 @@
 #include <linux/ioctl.h>
 #include <asm/kvm.h>
 #define KVM_API_VERSION 12
-#define KVM_TRC_SHIFT 16
-#define KVM_TRC_ENTRYEXIT (1 << KVM_TRC_SHIFT)
-#define KVM_TRC_HANDLER (1 << (KVM_TRC_SHIFT + 1))
-#define KVM_TRC_VMENTRY (KVM_TRC_ENTRYEXIT + 0x01)
-#define KVM_TRC_VMEXIT (KVM_TRC_ENTRYEXIT + 0x02)
-#define KVM_TRC_PAGE_FAULT (KVM_TRC_HANDLER + 0x01)
-#define KVM_TRC_HEAD_SIZE 12
-#define KVM_TRC_CYCLE_SIZE 8
-#define KVM_TRC_EXTRA_MAX 7
-#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02)
-#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03)
-#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04)
-#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05)
-#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06)
-#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07)
-#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08)
-#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09)
-#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A)
-#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B)
-#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C)
-#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D)
-#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E)
-#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F)
-#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10)
-#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11)
-#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12)
-#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13)
-#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14)
-#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15)
-#define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16)
-#define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17)
-#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18)
-#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19)
-struct kvm_user_trace_setup {
-  __u32 buf_size;
-  __u32 buf_nr;
-};
-#define __KVM_DEPRECATED_MAIN_W_0x06 _IOW(KVMIO, 0x06, struct kvm_user_trace_setup)
-#define __KVM_DEPRECATED_MAIN_0x07 _IO(KVMIO, 0x07)
-#define __KVM_DEPRECATED_MAIN_0x08 _IO(KVMIO, 0x08)
-#define __KVM_DEPRECATED_VM_R_0x70 _IOR(KVMIO, 0x70, struct kvm_assigned_irq)
-struct kvm_breakpoint {
-  __u32 enabled;
-  __u32 padding;
-  __u64 address;
-};
-struct kvm_debug_guest {
-  __u32 enabled;
-  __u32 pad;
-  struct kvm_breakpoint breakpoints[4];
-  __u32 singlestep;
-};
-#define __KVM_DEPRECATED_VCPU_W_0x87 _IOW(KVMIO, 0x87, struct kvm_debug_guest)
 struct kvm_userspace_memory_region {
   __u32 slot;
   __u32 flags;
@@ -72,8 +19,20 @@
   __u64 memory_size;
   __u64 userspace_addr;
 };
+struct kvm_userspace_memory_region2 {
+  __u32 slot;
+  __u32 flags;
+  __u64 guest_phys_addr;
+  __u64 memory_size;
+  __u64 userspace_addr;
+  __u64 guest_memfd_offset;
+  __u32 guest_memfd;
+  __u32 pad1;
+  __u64 pad2[14];
+};
 #define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0)
 #define KVM_MEM_READONLY (1UL << 1)
+#define KVM_MEM_GUEST_MEMFD (1UL << 2)
 struct kvm_irq_level {
   union {
     __u32 irq;
@@ -201,6 +160,7 @@
 #define KVM_EXIT_RISCV_CSR 36
 #define KVM_EXIT_NOTIFY 37
 #define KVM_EXIT_LOONGARCH_IOCSR 38
+#define KVM_EXIT_MEMORY_FAULT 39
 #define KVM_INTERNAL_ERROR_EMULATION 1
 #define KVM_INTERNAL_ERROR_SIMUL_EX 2
 #define KVM_INTERNAL_ERROR_DELIVERY_EV 3
@@ -383,6 +343,12 @@
 #define KVM_NOTIFY_CONTEXT_INVALID (1 << 0)
       __u32 flags;
     } notify;
+    struct {
+#define KVM_MEMORY_EXIT_FLAG_PRIVATE (1ULL << 3)
+      __u64 flags;
+      __u64 gpa;
+      __u64 size;
+    } memory_fault;
     char padding[256];
   };
 #define SYNC_REGS_SIZE_BYTES 2048
@@ -683,9 +649,6 @@
 #define KVM_CHECK_EXTENSION _IO(KVMIO, 0x03)
 #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04)
 #define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2)
-#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06
-#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07
-#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08
 #define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2)
 #define KVM_GET_MSR_FEATURE_INDEX_LIST _IOWR(KVMIO, 0x0a, struct kvm_msr_list)
 #define KVM_CAP_IRQCHIP 0
@@ -933,6 +896,11 @@
 #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228
 #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229
 #define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230
+#define KVM_CAP_USER_MEMORY2 231
+#define KVM_CAP_MEMORY_FAULT_INFO 232
+#define KVM_CAP_MEMORY_ATTRIBUTES 233
+#define KVM_CAP_GUEST_MEMFD 234
+#define KVM_CAP_VM_TYPES 235
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -1008,6 +976,7 @@
 #define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
 #define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
 #define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
+#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
 struct kvm_xen_hvm_config {
   __u32 flags;
   __u32 msr;
@@ -1148,6 +1117,7 @@
 #define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, struct kvm_userspace_memory_region)
 #define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
+#define KVM_SET_USER_MEMORY_REGION2 _IOW(KVMIO, 0x49, struct kvm_userspace_memory_region2)
 struct kvm_s390_ucas_mapping {
   __u64 user_addr;
   __u64 vcpu_addr;
@@ -1166,15 +1136,8 @@
 #define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level)
 #define KVM_REGISTER_COALESCED_MMIO _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone)
 #define KVM_UNREGISTER_COALESCED_MMIO _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone)
-#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, struct kvm_assigned_pci_dev)
 #define KVM_SET_GSI_ROUTING _IOW(KVMIO, 0x6a, struct kvm_irq_routing)
-#define KVM_ASSIGN_IRQ __KVM_DEPRECATED_VM_R_0x70
-#define KVM_ASSIGN_DEV_IRQ _IOW(KVMIO, 0x70, struct kvm_assigned_irq)
 #define KVM_REINJECT_CONTROL _IO(KVMIO, 0x71)
-#define KVM_DEASSIGN_PCI_DEVICE _IOW(KVMIO, 0x72, struct kvm_assigned_pci_dev)
-#define KVM_ASSIGN_SET_MSIX_NR _IOW(KVMIO, 0x73, struct kvm_assigned_msix_nr)
-#define KVM_ASSIGN_SET_MSIX_ENTRY _IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
-#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
 #define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd)
 #define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config)
 #define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78)
@@ -1187,7 +1150,6 @@
 #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo)
 #define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2)
 #define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3)
-#define KVM_ASSIGN_SET_INTX_MASK _IOW(KVMIO, 0xa4, struct kvm_assigned_pci_dev)
 #define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi)
 #define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info)
 #define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
@@ -1218,7 +1180,6 @@
 #define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs)
 #define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation)
 #define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt)
-#define KVM_DEBUG_GUEST __KVM_DEPRECATED_VCPU_W_0x87
 #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
 #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs)
 #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid)
@@ -1679,4 +1640,18 @@
 #define KVM_S390_ZPCIOP_REG_AEN 0
 #define KVM_S390_ZPCIOP_DEREG_AEN 1
 #define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0)
+#define KVM_SET_MEMORY_ATTRIBUTES _IOW(KVMIO, 0xd2, struct kvm_memory_attributes)
+struct kvm_memory_attributes {
+  __u64 address;
+  __u64 size;
+  __u64 attributes;
+  __u64 flags;
+};
+#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)
+#define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd)
+struct kvm_create_guest_memfd {
+  __u64 size;
+  __u64 flags;
+  __u64 reserved[6];
+};
 #endif
diff --git a/libc/kernel/uapi/linux/lsm.h b/libc/kernel/uapi/linux/lsm.h
new file mode 100644
index 0000000..9d538ee
--- /dev/null
+++ b/libc/kernel/uapi/linux/lsm.h
@@ -0,0 +1,39 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_LSM_H
+#define _UAPI_LINUX_LSM_H
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+struct lsm_ctx {
+  __u64 id;
+  __u64 flags;
+  __u64 len;
+  __u64 ctx_len;
+  __u8 ctx[] __counted_by(ctx_len);
+};
+#define LSM_ID_UNDEF 0
+#define LSM_ID_CAPABILITY 100
+#define LSM_ID_SELINUX 101
+#define LSM_ID_SMACK 102
+#define LSM_ID_TOMOYO 103
+#define LSM_ID_APPARMOR 104
+#define LSM_ID_YAMA 105
+#define LSM_ID_LOADPIN 106
+#define LSM_ID_SAFESETID 107
+#define LSM_ID_LOCKDOWN 108
+#define LSM_ID_BPF 109
+#define LSM_ID_LANDLOCK 110
+#define LSM_ATTR_UNDEF 0
+#define LSM_ATTR_CURRENT 100
+#define LSM_ATTR_EXEC 101
+#define LSM_ATTR_FSCREATE 102
+#define LSM_ATTR_KEYCREATE 103
+#define LSM_ATTR_PREV 104
+#define LSM_ATTR_SOCKCREATE 105
+#define LSM_FLAG_SINGLE 0x0001
+#endif
diff --git a/libc/kernel/uapi/linux/mount.h b/libc/kernel/uapi/linux/mount.h
index faef8af..1166a7a 100644
--- a/libc/kernel/uapi/linux/mount.h
+++ b/libc/kernel/uapi/linux/mount.h
@@ -88,4 +88,41 @@
   __u64 userns_fd;
 };
 #define MOUNT_ATTR_SIZE_VER0 32
+struct statmount {
+  __u32 size;
+  __u32 __spare1;
+  __u64 mask;
+  __u32 sb_dev_major;
+  __u32 sb_dev_minor;
+  __u64 sb_magic;
+  __u32 sb_flags;
+  __u32 fs_type;
+  __u64 mnt_id;
+  __u64 mnt_parent_id;
+  __u32 mnt_id_old;
+  __u32 mnt_parent_id_old;
+  __u64 mnt_attr;
+  __u64 mnt_propagation;
+  __u64 mnt_peer_group;
+  __u64 mnt_master;
+  __u64 propagate_from;
+  __u32 mnt_root;
+  __u32 mnt_point;
+  __u64 __spare2[50];
+  char str[];
+};
+struct mnt_id_req {
+  __u32 size;
+  __u32 spare;
+  __u64 mnt_id;
+  __u64 param;
+};
+#define MNT_ID_REQ_SIZE_VER0 24
+#define STATMOUNT_SB_BASIC 0x00000001U
+#define STATMOUNT_MNT_BASIC 0x00000002U
+#define STATMOUNT_PROPAGATE_FROM 0x00000004U
+#define STATMOUNT_MNT_ROOT 0x00000008U
+#define STATMOUNT_MNT_POINT 0x00000010U
+#define STATMOUNT_FS_TYPE 0x00000020U
+#define LSMT_ROOT 0xffffffffffffffff
 #endif
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index 6f5d272..3c9ba5e 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -52,6 +52,7 @@
   __u64 mptcpi_bytes_sent;
   __u64 mptcpi_bytes_received;
   __u64 mptcpi_bytes_acked;
+  __u8 mptcpi_subflows_total;
 };
 #define MPTCP_RST_EUNSPEC 0
 #define MPTCP_RST_EMPTCP 1
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
index 3c5cb94..6d90ae4 100644
--- a/libc/kernel/uapi/linux/netdev.h
+++ b/libc/kernel/uapi/linux/netdev.h
@@ -21,7 +21,15 @@
 enum netdev_xdp_rx_metadata {
   NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
   NETDEV_XDP_RX_METADATA_HASH = 2,
-  NETDEV_XDP_RX_METADATA_MASK = 3,
+  NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
+};
+enum netdev_xsk_flags {
+  NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
+  NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
+};
+enum netdev_queue_type {
+  NETDEV_QUEUE_TYPE_RX,
+  NETDEV_QUEUE_TYPE_TX,
 };
 enum {
   NETDEV_A_DEV_IFINDEX = 1,
@@ -29,16 +37,67 @@
   NETDEV_A_DEV_XDP_FEATURES,
   NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
   NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
+  NETDEV_A_DEV_XSK_FEATURES,
   __NETDEV_A_DEV_MAX,
   NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
 };
 enum {
+  NETDEV_A_PAGE_POOL_ID = 1,
+  NETDEV_A_PAGE_POOL_IFINDEX,
+  NETDEV_A_PAGE_POOL_NAPI_ID,
+  NETDEV_A_PAGE_POOL_INFLIGHT,
+  NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
+  NETDEV_A_PAGE_POOL_DETACH_TIME,
+  __NETDEV_A_PAGE_POOL_MAX,
+  NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1)
+};
+enum {
+  NETDEV_A_PAGE_POOL_STATS_INFO = 1,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_FAST = 8,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW_HIGH_ORDER,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_EMPTY,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_REFILL,
+  NETDEV_A_PAGE_POOL_STATS_ALLOC_WAIVE,
+  NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHED,
+  NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHE_FULL,
+  NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING,
+  NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING_FULL,
+  NETDEV_A_PAGE_POOL_STATS_RECYCLE_RELEASED_REFCNT,
+  __NETDEV_A_PAGE_POOL_STATS_MAX,
+  NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
+};
+enum {
+  NETDEV_A_NAPI_IFINDEX = 1,
+  NETDEV_A_NAPI_ID,
+  NETDEV_A_NAPI_IRQ,
+  NETDEV_A_NAPI_PID,
+  __NETDEV_A_NAPI_MAX,
+  NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
+};
+enum {
+  NETDEV_A_QUEUE_ID = 1,
+  NETDEV_A_QUEUE_IFINDEX,
+  NETDEV_A_QUEUE_TYPE,
+  NETDEV_A_QUEUE_NAPI_ID,
+  __NETDEV_A_QUEUE_MAX,
+  NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
+};
+enum {
   NETDEV_CMD_DEV_GET = 1,
   NETDEV_CMD_DEV_ADD_NTF,
   NETDEV_CMD_DEV_DEL_NTF,
   NETDEV_CMD_DEV_CHANGE_NTF,
+  NETDEV_CMD_PAGE_POOL_GET,
+  NETDEV_CMD_PAGE_POOL_ADD_NTF,
+  NETDEV_CMD_PAGE_POOL_DEL_NTF,
+  NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
+  NETDEV_CMD_PAGE_POOL_STATS_GET,
+  NETDEV_CMD_QUEUE_GET,
+  NETDEV_CMD_NAPI_GET,
   __NETDEV_CMD_MAX,
   NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
 };
 #define NETDEV_MCGRP_MGMT "mgmt"
+#define NETDEV_MCGRP_PAGE_POOL "page-pool"
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 1d0af17..2216fa8 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -157,6 +157,7 @@
 };
 #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
 enum nft_rule_compat_flags {
+  NFT_RULE_COMPAT_F_UNUSED = (1 << 0),
   NFT_RULE_COMPAT_F_INV = (1 << 1),
   NFT_RULE_COMPAT_F_MASK = NFT_RULE_COMPAT_F_INV,
 };
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index bf87c0e..3286d9b 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -180,6 +180,7 @@
   NL80211_CMD_REMOVE_LINK_STA,
   NL80211_CMD_SET_HW_TIMESTAMP,
   NL80211_CMD_LINKS_REMOVED,
+  NL80211_CMD_SET_TID_TO_LINK_MAPPING,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -523,6 +524,9 @@
   NL80211_ATTR_HW_TIMESTAMP_ENABLED,
   NL80211_ATTR_EMA_RNR_ELEMS,
   NL80211_ATTR_MLO_LINK_DISABLED,
+  NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
+  NL80211_ATTR_MLO_TTLM_DLINK,
+  NL80211_ATTR_MLO_TTLM_ULINK,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -868,6 +872,9 @@
   NL80211_FREQUENCY_ATTR_NO_320MHZ,
   NL80211_FREQUENCY_ATTR_NO_EHT,
   NL80211_FREQUENCY_ATTR_PSD,
+  NL80211_FREQUENCY_ATTR_DFS_CONCURRENT,
+  NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT,
+  NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT,
   __NL80211_FREQUENCY_ATTR_AFTER_LAST,
   NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
 };
@@ -940,6 +947,9 @@
   NL80211_RRF_NO_320MHZ = 1 << 18,
   NL80211_RRF_NO_EHT = 1 << 19,
   NL80211_RRF_PSD = 1 << 20,
+  NL80211_RRF_DFS_CONCURRENT = 1 << 21,
+  NL80211_RRF_NO_UHB_VLP_CLIENT = 1 << 22,
+  NL80211_RRF_NO_UHB_AFC_CLIENT = 1 << 23,
 };
 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
 #define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
@@ -1104,6 +1114,14 @@
   NL80211_BSS_CHAN_WIDTH_1,
   NL80211_BSS_CHAN_WIDTH_2,
 };
+enum nl80211_bss_use_for {
+  NL80211_BSS_USE_FOR_NORMAL = 1 << 0,
+  NL80211_BSS_USE_FOR_MLD_LINK = 1 << 1,
+};
+enum nl80211_bss_cannot_use_reasons {
+  NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 1 << 0,
+  NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 1 << 1,
+};
 enum nl80211_bss {
   __NL80211_BSS_INVALID,
   NL80211_BSS_BSSID,
@@ -1128,6 +1146,8 @@
   NL80211_BSS_FREQUENCY_OFFSET,
   NL80211_BSS_MLO_LINK_ID,
   NL80211_BSS_MLD_ADDR,
+  NL80211_BSS_USE_FOR,
+  NL80211_BSS_CANNOT_USE_REASONS,
   __NL80211_BSS_AFTER_LAST,
   NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1
 };
@@ -1547,6 +1567,7 @@
   NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
   NL80211_EXT_FEATURE_OWE_OFFLOAD,
   NL80211_EXT_FEATURE_OWE_OFFLOAD_AP,
+  NL80211_EXT_FEATURE_DFS_CONCURRENT,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
diff --git a/libc/kernel/uapi/linux/nsm.h b/libc/kernel/uapi/linux/nsm.h
new file mode 100644
index 0000000..5c8e27d
--- /dev/null
+++ b/libc/kernel/uapi/linux/nsm.h
@@ -0,0 +1,23 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __UAPI_LINUX_NSM_H
+#define __UAPI_LINUX_NSM_H
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define NSM_MAGIC 0x0A
+#define NSM_REQUEST_MAX_SIZE 0x1000
+#define NSM_RESPONSE_MAX_SIZE 0x3000
+struct nsm_iovec {
+  __u64 addr;
+  __u64 len;
+};
+struct nsm_raw {
+  struct nsm_iovec request;
+  struct nsm_iovec response;
+};
+#define NSM_IOCTL_RAW _IOWR(NSM_MAGIC, 0x0, struct nsm_raw)
+#endif
diff --git a/libc/kernel/uapi/linux/pcitest.h b/libc/kernel/uapi/linux/pcitest.h
index 2e8e761..38e498d 100644
--- a/libc/kernel/uapi/linux/pcitest.h
+++ b/libc/kernel/uapi/linux/pcitest.h
@@ -7,7 +7,8 @@
 #ifndef __UAPI_LINUX_PCITEST_H
 #define __UAPI_LINUX_PCITEST_H
 #define PCITEST_BAR _IO('P', 0x1)
-#define PCITEST_LEGACY_IRQ _IO('P', 0x2)
+#define PCITEST_INTX_IRQ _IO('P', 0x2)
+#define PCITEST_LEGACY_IRQ PCITEST_INTX_IRQ
 #define PCITEST_MSI _IOW('P', 0x3, int)
 #define PCITEST_WRITE _IOW('P', 0x4, unsigned long)
 #define PCITEST_READ _IOW('P', 0x5, unsigned long)
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 4b01018..16a1a2e 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -118,6 +118,7 @@
   PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16,
   PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT = 17,
   PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT = 18,
+  PERF_SAMPLE_BRANCH_COUNTERS_SHIFT = 19,
   PERF_SAMPLE_BRANCH_MAX_SHIFT
 };
 enum perf_branch_sample_type {
@@ -140,6 +141,7 @@
   PERF_SAMPLE_BRANCH_TYPE_SAVE = 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT,
   PERF_SAMPLE_BRANCH_HW_INDEX = 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
   PERF_SAMPLE_BRANCH_PRIV_SAVE = 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
+  PERF_SAMPLE_BRANCH_COUNTERS = 1U << PERF_SAMPLE_BRANCH_COUNTERS_SHIFT,
   PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
 enum {
@@ -502,6 +504,7 @@
   __u64 to;
   __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, type : 4, spec : 2, new_type : 4, priv : 3, reserved : 31;
 };
+#define PERF_BRANCH_ENTRY_INFO_BITS_MAX 33
 union perf_sample_weight {
   __u64 full;
 #ifdef __LITTLE_ENDIAN_BITFIELD
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index 8ea50d4..b402fa6 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -205,30 +205,6 @@
 #define TC_U32_EAT 8
 #define TC_U32_MAXDEPTH 8
 enum {
-  TCA_RSVP_UNSPEC,
-  TCA_RSVP_CLASSID,
-  TCA_RSVP_DST,
-  TCA_RSVP_SRC,
-  TCA_RSVP_PINFO,
-  TCA_RSVP_POLICE,
-  TCA_RSVP_ACT,
-  __TCA_RSVP_MAX
-};
-#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1)
-struct tc_rsvp_gpi {
-  __u32 key;
-  __u32 mask;
-  int offset;
-};
-struct tc_rsvp_pinfo {
-  struct tc_rsvp_gpi dpi;
-  struct tc_rsvp_gpi spi;
-  __u8 protocol;
-  __u8 tunnelid;
-  __u8 tunnelhdr;
-  __u8 pad;
-};
-enum {
   TCA_ROUTE4_UNSPEC,
   TCA_ROUTE4_CLASSID,
   TCA_ROUTE4_TO,
@@ -250,18 +226,6 @@
 };
 #define TCA_FW_MAX (__TCA_FW_MAX - 1)
 enum {
-  TCA_TCINDEX_UNSPEC,
-  TCA_TCINDEX_HASH,
-  TCA_TCINDEX_MASK,
-  TCA_TCINDEX_SHIFT,
-  TCA_TCINDEX_FALL_THROUGH,
-  TCA_TCINDEX_CLASSID,
-  TCA_TCINDEX_POLICE,
-  TCA_TCINDEX_ACT,
-  __TCA_TCINDEX_MAX
-};
-#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
-enum {
   FLOW_KEY_SRC,
   FLOW_KEY_DST,
   FLOW_KEY_PROTO,
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index 9047c8e..c3488c2 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -327,95 +327,6 @@
   __TCA_HFSC_MAX,
 };
 #define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1)
-#define TC_CBQ_MAXPRIO 8
-#define TC_CBQ_MAXLEVEL 8
-#define TC_CBQ_DEF_EWMA 5
-struct tc_cbq_lssopt {
-  unsigned char change;
-  unsigned char flags;
-#define TCF_CBQ_LSS_BOUNDED 1
-#define TCF_CBQ_LSS_ISOLATED 2
-  unsigned char ewma_log;
-  unsigned char level;
-#define TCF_CBQ_LSS_FLAGS 1
-#define TCF_CBQ_LSS_EWMA 2
-#define TCF_CBQ_LSS_MAXIDLE 4
-#define TCF_CBQ_LSS_MINIDLE 8
-#define TCF_CBQ_LSS_OFFTIME 0x10
-#define TCF_CBQ_LSS_AVPKT 0x20
-  __u32 maxidle;
-  __u32 minidle;
-  __u32 offtime;
-  __u32 avpkt;
-};
-struct tc_cbq_wrropt {
-  unsigned char flags;
-  unsigned char priority;
-  unsigned char cpriority;
-  unsigned char __reserved;
-  __u32 allot;
-  __u32 weight;
-};
-struct tc_cbq_ovl {
-  unsigned char strategy;
-#define TC_CBQ_OVL_CLASSIC 0
-#define TC_CBQ_OVL_DELAY 1
-#define TC_CBQ_OVL_LOWPRIO 2
-#define TC_CBQ_OVL_DROP 3
-#define TC_CBQ_OVL_RCLASSIC 4
-  unsigned char priority2;
-  __u16 pad;
-  __u32 penalty;
-};
-struct tc_cbq_police {
-  unsigned char police;
-  unsigned char __res1;
-  unsigned short __res2;
-};
-struct tc_cbq_fopt {
-  __u32 split;
-  __u32 defmap;
-  __u32 defchange;
-};
-struct tc_cbq_xstats {
-  __u32 borrows;
-  __u32 overactions;
-  __s32 avgidle;
-  __s32 undertime;
-};
-enum {
-  TCA_CBQ_UNSPEC,
-  TCA_CBQ_LSSOPT,
-  TCA_CBQ_WRROPT,
-  TCA_CBQ_FOPT,
-  TCA_CBQ_OVL_STRATEGY,
-  TCA_CBQ_RATE,
-  TCA_CBQ_RTAB,
-  TCA_CBQ_POLICE,
-  __TCA_CBQ_MAX,
-};
-#define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1)
-enum {
-  TCA_DSMARK_UNSPEC,
-  TCA_DSMARK_INDICES,
-  TCA_DSMARK_DEFAULT_INDEX,
-  TCA_DSMARK_SET_TC_INDEX,
-  TCA_DSMARK_MASK,
-  TCA_DSMARK_VALUE,
-  __TCA_DSMARK_MAX,
-};
-#define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1)
-enum {
-  TCA_ATM_UNSPEC,
-  TCA_ATM_FD,
-  TCA_ATM_PTR,
-  TCA_ATM_HDR,
-  TCA_ATM_EXCESS,
-  TCA_ATM_ADDR,
-  TCA_ATM_STATE,
-  __TCA_ATM_MAX,
-};
-#define TCA_ATM_MAX (__TCA_ATM_MAX - 1)
 enum {
   TCA_NETEM_UNSPEC,
   TCA_NETEM_CORR,
diff --git a/libc/kernel/uapi/linux/raid/md_u.h b/libc/kernel/uapi/linux/raid/md_u.h
index f5ae289..f291f64 100644
--- a/libc/kernel/uapi/linux/raid/md_u.h
+++ b/libc/kernel/uapi/linux/raid/md_u.h
@@ -57,9 +57,6 @@
   int layout;
   int chunk_size;
 } mdu_array_info_t;
-#define LEVEL_MULTIPATH (- 4)
-#define LEVEL_LINEAR (- 1)
-#define LEVEL_FAULTY (- 5)
 #define LEVEL_NONE (- 1000000)
 typedef struct mdu_disk_info_s {
   int number;
diff --git a/libc/kernel/uapi/linux/resource.h b/libc/kernel/uapi/linux/resource.h
index e64c79e..05e201b 100644
--- a/libc/kernel/uapi/linux/resource.h
+++ b/libc/kernel/uapi/linux/resource.h
@@ -6,7 +6,7 @@
  */
 #ifndef _UAPI_LINUX_RESOURCE_H
 #define _UAPI_LINUX_RESOURCE_H
-#include <linux/time.h>
+#include <linux/time_types.h>
 #include <linux/types.h>
 #define RUSAGE_SELF 0
 #define RUSAGE_CHILDREN (- 1)
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index adbdd1b..ed5ed66 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -6,6 +6,7 @@
  */
 #ifndef _UAPI_LINUX_SERIAL_H
 #define _UAPI_LINUX_SERIAL_H
+#include <linux/const.h>
 #include <linux/types.h>
 #include <linux/tty_flags.h>
 struct serial_struct {
@@ -79,14 +80,15 @@
 };
 struct serial_rs485 {
   __u32 flags;
-#define SER_RS485_ENABLED (1 << 0)
-#define SER_RS485_RTS_ON_SEND (1 << 1)
-#define SER_RS485_RTS_AFTER_SEND (1 << 2)
-#define SER_RS485_RX_DURING_TX (1 << 4)
-#define SER_RS485_TERMINATE_BUS (1 << 5)
-#define SER_RS485_ADDRB (1 << 6)
-#define SER_RS485_ADDR_RECV (1 << 7)
-#define SER_RS485_ADDR_DEST (1 << 8)
+#define SER_RS485_ENABLED _BITUL(0)
+#define SER_RS485_RTS_ON_SEND _BITUL(1)
+#define SER_RS485_RTS_AFTER_SEND _BITUL(2)
+#define SER_RS485_RX_DURING_TX _BITUL(4)
+#define SER_RS485_TERMINATE_BUS _BITUL(5)
+#define SER_RS485_ADDRB _BITUL(6)
+#define SER_RS485_ADDR_RECV _BITUL(7)
+#define SER_RS485_ADDR_DEST _BITUL(8)
+#define SER_RS485_MODE_RS422 _BITUL(9)
   __u32 delay_rts_before_send;
   __u32 delay_rts_after_send;
   union {
diff --git a/libc/kernel/uapi/linux/smc.h b/libc/kernel/uapi/linux/smc.h
index 4521ceb..5e75fac 100644
--- a/libc/kernel/uapi/linux/smc.h
+++ b/libc/kernel/uapi/linux/smc.h
@@ -132,6 +132,8 @@
   SMC_NLA_LGR_D_CHID,
   SMC_NLA_LGR_D_PAD,
   SMC_NLA_LGR_D_V2_COMMON,
+  SMC_NLA_LGR_D_EXT_GID,
+  SMC_NLA_LGR_D_PEER_EXT_GID,
   __SMC_NLA_LGR_D_MAX,
   SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
 };
diff --git a/libc/kernel/uapi/linux/smc_diag.h b/libc/kernel/uapi/linux/smc_diag.h
index be540ac..b358acf 100644
--- a/libc/kernel/uapi/linux/smc_diag.h
+++ b/libc/kernel/uapi/linux/smc_diag.h
@@ -85,5 +85,7 @@
   __aligned_u64 my_gid;
   __aligned_u64 token;
   __aligned_u64 peer_token;
+  __aligned_u64 peer_gid_ext;
+  __aligned_u64 my_gid_ext;
 };
 #endif
diff --git a/libc/kernel/uapi/linux/stat.h b/libc/kernel/uapi/linux/stat.h
index 2fb7437..9974f3e 100644
--- a/libc/kernel/uapi/linux/stat.h
+++ b/libc/kernel/uapi/linux/stat.h
@@ -85,6 +85,7 @@
 #define STATX_BTIME 0x00000800U
 #define STATX_MNT_ID 0x00001000U
 #define STATX_DIOALIGN 0x00002000U
+#define STATX_MNT_ID_UNIQUE 0x00004000U
 #define STATX__RESERVED 0x80000000U
 #define STATX_ALL 0x00000fffU
 #define STATX_ATTR_COMPRESSED 0x00000004
diff --git a/libc/kernel/uapi/linux/sync_file.h b/libc/kernel/uapi/linux/sync_file.h
index 423d248..bde8c16 100644
--- a/libc/kernel/uapi/linux/sync_file.h
+++ b/libc/kernel/uapi/linux/sync_file.h
@@ -30,7 +30,12 @@
   __u32 pad;
   __u64 sync_fence_info;
 };
+struct sync_set_deadline {
+  __u64 deadline_ns;
+  __u64 pad;
+};
 #define SYNC_IOC_MAGIC '>'
 #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
 #define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
+#define SYNC_IOC_SET_DEADLINE _IOW(SYNC_IOC_MAGIC, 5, struct sync_set_deadline)
 #endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_ipt.h b/libc/kernel/uapi/linux/tc_act/tc_ipt.h
deleted file mode 100644
index a2fc933..0000000
--- a/libc/kernel/uapi/linux/tc_act/tc_ipt.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is auto-generated. Modifications will be lost.
- *
- * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
- * for more information.
- */
-#ifndef __LINUX_TC_IPT_H
-#define __LINUX_TC_IPT_H
-#include <linux/pkt_cls.h>
-enum {
-  TCA_IPT_UNSPEC,
-  TCA_IPT_TABLE,
-  TCA_IPT_HOOK,
-  TCA_IPT_INDEX,
-  TCA_IPT_CNT,
-  TCA_IPT_TM,
-  TCA_IPT_TARG,
-  TCA_IPT_PAD,
-  __TCA_IPT_MAX
-};
-#define TCA_IPT_MAX (__TCA_IPT_MAX - 1)
-#endif
diff --git a/libc/kernel/uapi/linux/tc_act/tc_mirred.h b/libc/kernel/uapi/linux/tc_act/tc_mirred.h
index d87b74a..dc51bc7 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_mirred.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_mirred.h
@@ -22,6 +22,7 @@
   TCA_MIRRED_TM,
   TCA_MIRRED_PARMS,
   TCA_MIRRED_PAD,
+  TCA_MIRRED_BLOCKID,
   __TCA_MIRRED_MAX
 };
 #define TCA_MIRRED_MAX (__TCA_MIRRED_MAX - 1)
diff --git a/libc/kernel/uapi/linux/thp7312.h b/libc/kernel/uapi/linux/thp7312.h
new file mode 100644
index 0000000..fbd5571
--- /dev/null
+++ b/libc/kernel/uapi/linux/thp7312.h
@@ -0,0 +1,14 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __UAPI_THP7312_H_
+#define __UAPI_THP7312_H_
+#include <linux/v4l2-controls.h>
+#define V4L2_CID_THP7312_LOW_LIGHT_COMPENSATION (V4L2_CID_USER_THP7312_BASE + 0x01)
+#define V4L2_CID_THP7312_AUTO_FOCUS_METHOD (V4L2_CID_USER_THP7312_BASE + 0x02)
+#define V4L2_CID_THP7312_NOISE_REDUCTION_AUTO (V4L2_CID_USER_THP7312_BASE + 0x03)
+#define V4L2_CID_THP7312_NOISE_REDUCTION_ABSOLUTE (V4L2_CID_USER_THP7312_BASE + 0x04)
+#endif
diff --git a/libc/kernel/uapi/linux/time_types.h b/libc/kernel/uapi/linux/time_types.h
index 668f6ae..bca8698 100644
--- a/libc/kernel/uapi/linux/time_types.h
+++ b/libc/kernel/uapi/linux/time_types.h
@@ -6,6 +6,7 @@
  */
 #ifndef _UAPI_LINUX_TIME_TYPES_H
 #define _UAPI_LINUX_TIME_TYPES_H
+#include <linux/time.h>
 #include <linux/types.h>
 struct __kernel_timespec {
   __kernel_time64_t tv_sec;
diff --git a/libc/kernel/uapi/linux/usb/f_accessory.h b/libc/kernel/uapi/linux/usb/f_accessory.h
deleted file mode 100644
index abd864c..0000000
--- a/libc/kernel/uapi/linux/usb/f_accessory.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This file is auto-generated. Modifications will be lost.
- *
- * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
- * for more information.
- */
-#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H
-#define _UAPI_LINUX_USB_F_ACCESSORY_H
-#define USB_ACCESSORY_VENDOR_ID 0x18D1
-#define USB_ACCESSORY_PRODUCT_ID 0x2D00
-#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
-#define ACCESSORY_STRING_MANUFACTURER 0
-#define ACCESSORY_STRING_MODEL 1
-#define ACCESSORY_STRING_DESCRIPTION 2
-#define ACCESSORY_STRING_VERSION 3
-#define ACCESSORY_STRING_URI 4
-#define ACCESSORY_STRING_SERIAL 5
-#define ACCESSORY_GET_PROTOCOL 51
-#define ACCESSORY_SEND_STRING 52
-#define ACCESSORY_START 53
-#define ACCESSORY_REGISTER_HID 54
-#define ACCESSORY_UNREGISTER_HID 55
-#define ACCESSORY_SET_HID_REPORT_DESC 56
-#define ACCESSORY_SEND_HID_EVENT 57
-#define ACCESSORY_SET_AUDIO_MODE 58
-#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
-#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
-#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
-#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
-#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
-#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
-#define ACCESSORY_IS_START_REQUESTED _IO('M', 7)
-#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8)
-#endif
diff --git a/libc/kernel/uapi/linux/usb/functionfs.h b/libc/kernel/uapi/linux/usb/functionfs.h
index 889360e..417093e 100644
--- a/libc/kernel/uapi/linux/usb/functionfs.h
+++ b/libc/kernel/uapi/linux/usb/functionfs.h
@@ -59,8 +59,9 @@
 struct usb_ext_compat_desc {
   __u8 bFirstInterfaceNumber;
   __u8 Reserved1;
-  __u8 CompatibleID[8];
+  __struct_group(, IDs,, __u8 CompatibleID[8];
   __u8 SubCompatibleID[8];
+ );
   __u8 Reserved2[6];
 };
 struct usb_ext_prop_desc {
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index 5eeea4e..1dc2d79 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -11,15 +11,16 @@
 #define USERFAULTFD_IOC_NEW _IO(USERFAULTFD_IOC, 0x00)
 #define UFFD_API ((__u64) 0xAA)
 #define UFFD_API_REGISTER_MODES (UFFDIO_REGISTER_MODE_MISSING | UFFDIO_REGISTER_MODE_WP | UFFDIO_REGISTER_MODE_MINOR)
-#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM | UFFD_FEATURE_EXACT_ADDRESS | UFFD_FEATURE_WP_HUGETLBFS_SHMEM | UFFD_FEATURE_WP_UNPOPULATED | UFFD_FEATURE_POISON | UFFD_FEATURE_WP_ASYNC)
+#define UFFD_API_FEATURES (UFFD_FEATURE_PAGEFAULT_FLAG_WP | UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM | UFFD_FEATURE_SIGBUS | UFFD_FEATURE_THREAD_ID | UFFD_FEATURE_MINOR_HUGETLBFS | UFFD_FEATURE_MINOR_SHMEM | UFFD_FEATURE_EXACT_ADDRESS | UFFD_FEATURE_WP_HUGETLBFS_SHMEM | UFFD_FEATURE_WP_UNPOPULATED | UFFD_FEATURE_POISON | UFFD_FEATURE_WP_ASYNC | UFFD_FEATURE_MOVE)
 #define UFFD_API_IOCTLS ((__u64) 1 << _UFFDIO_REGISTER | (__u64) 1 << _UFFDIO_UNREGISTER | (__u64) 1 << _UFFDIO_API)
-#define UFFD_API_RANGE_IOCTLS ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_ZEROPAGE | (__u64) 1 << _UFFDIO_WRITEPROTECT | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_POISON)
+#define UFFD_API_RANGE_IOCTLS ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_ZEROPAGE | (__u64) 1 << _UFFDIO_MOVE | (__u64) 1 << _UFFDIO_WRITEPROTECT | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_POISON)
 #define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_WRITEPROTECT | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_POISON)
 #define _UFFDIO_REGISTER (0x00)
 #define _UFFDIO_UNREGISTER (0x01)
 #define _UFFDIO_WAKE (0x02)
 #define _UFFDIO_COPY (0x03)
 #define _UFFDIO_ZEROPAGE (0x04)
+#define _UFFDIO_MOVE (0x05)
 #define _UFFDIO_WRITEPROTECT (0x06)
 #define _UFFDIO_CONTINUE (0x07)
 #define _UFFDIO_POISON (0x08)
@@ -31,6 +32,7 @@
 #define UFFDIO_WAKE _IOR(UFFDIO, _UFFDIO_WAKE, struct uffdio_range)
 #define UFFDIO_COPY _IOWR(UFFDIO, _UFFDIO_COPY, struct uffdio_copy)
 #define UFFDIO_ZEROPAGE _IOWR(UFFDIO, _UFFDIO_ZEROPAGE, struct uffdio_zeropage)
+#define UFFDIO_MOVE _IOWR(UFFDIO, _UFFDIO_MOVE, struct uffdio_move)
 #define UFFDIO_WRITEPROTECT _IOWR(UFFDIO, _UFFDIO_WRITEPROTECT, struct uffdio_writeprotect)
 #define UFFDIO_CONTINUE _IOWR(UFFDIO, _UFFDIO_CONTINUE, struct uffdio_continue)
 #define UFFDIO_POISON _IOWR(UFFDIO, _UFFDIO_POISON, struct uffdio_poison)
@@ -92,6 +94,7 @@
 #define UFFD_FEATURE_WP_UNPOPULATED (1 << 13)
 #define UFFD_FEATURE_POISON (1 << 14)
 #define UFFD_FEATURE_WP_ASYNC (1 << 15)
+#define UFFD_FEATURE_MOVE (1 << 16)
   __u64 features;
   __u64 ioctls;
 };
@@ -141,5 +144,14 @@
   __u64 mode;
   __s64 updated;
 };
+struct uffdio_move {
+  __u64 dst;
+  __u64 src;
+  __u64 len;
+#define UFFDIO_MOVE_MODE_DONTWAKE ((__u64) 1 << 0)
+#define UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES ((__u64) 1 << 1)
+  __u64 mode;
+  __s64 move;
+};
 #define UFFD_USER_MODE_ONLY 1
 #endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 90cb69d..23158dc 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -111,6 +111,7 @@
 #define V4L2_CID_USER_DW100_BASE (V4L2_CID_USER_BASE + 0x1190)
 #define V4L2_CID_USER_ASPEED_BASE (V4L2_CID_USER_BASE + 0x11a0)
 #define V4L2_CID_USER_NPCM_BASE (V4L2_CID_USER_BASE + 0x11b0)
+#define V4L2_CID_USER_THP7312_BASE (V4L2_CID_USER_BASE + 0x11c0)
 #define V4L2_CID_CODEC_BASE (V4L2_CTRL_CLASS_CODEC | 0x900)
 #define V4L2_CID_CODEC_CLASS (V4L2_CTRL_CLASS_CODEC | 1)
 #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_CODEC_BASE + 0)
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index d684a54..9caaa47 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -59,7 +59,8 @@
   __u32 pad;
   struct v4l2_fract interval;
   __u32 stream;
-  __u32 reserved[8];
+  __u32 which;
+  __u32 reserved[7];
 };
 struct v4l2_subdev_frame_interval_enum {
   __u32 index;
@@ -104,6 +105,7 @@
   __u32 reserved[6];
 };
 #define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1ULL << 0)
+#define V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH (1ULL << 1)
 struct v4l2_subdev_client_capability {
   __u64 capabilities;
 };
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 645a2ab..549c079 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -4,8 +4,8 @@
  * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
  * for more information.
  */
-#define LINUX_VERSION_CODE 395008
+#define LINUX_VERSION_CODE 395264
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 7
+#define LINUX_VERSION_PATCHLEVEL 8
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vfio.h b/libc/kernel/uapi/linux/vfio.h
index 1107b21..5910e40 100644
--- a/libc/kernel/uapi/linux/vfio.h
+++ b/libc/kernel/uapi/linux/vfio.h
@@ -336,6 +336,7 @@
   VFIO_DEVICE_STATE_RUNNING_P2P = 5,
   VFIO_DEVICE_STATE_PRE_COPY = 6,
   VFIO_DEVICE_STATE_PRE_COPY_P2P = 7,
+  VFIO_DEVICE_STATE_NR,
 };
 struct vfio_precopy_info {
   __u32 argsz;
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index bb98888..ed91484 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -562,6 +562,7 @@
 #define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)
 #define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5)
 #define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6)
+#define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7)
 struct v4l2_plane {
   __u32 bytesused;
   __u32 length;
@@ -911,7 +912,7 @@
     __s64  * p_s64;
     struct v4l2_area  * p_area;
     struct v4l2_ctrl_h264_sps  * p_h264_sps;
-    struct v4l2_ctrl_h264_pps * p_h264_pps;
+    struct v4l2_ctrl_h264_pps  * p_h264_pps;
     struct v4l2_ctrl_h264_scaling_matrix  * p_h264_scaling_matrix;
     struct v4l2_ctrl_h264_pred_weights  * p_h264_pred_weights;
     struct v4l2_ctrl_h264_slice_params  * p_h264_slice_params;
@@ -932,6 +933,8 @@
     struct v4l2_ctrl_av1_tile_group_entry  * p_av1_tile_group_entry;
     struct v4l2_ctrl_av1_frame  * p_av1_frame;
     struct v4l2_ctrl_av1_film_grain  * p_av1_film_grain;
+    struct v4l2_ctrl_hdr10_cll_info  * p_hdr10_cll_info;
+    struct v4l2_ctrl_hdr10_mastering_display  * p_hdr10_mastering_display;
     void  * ptr;
   };
 } __attribute__((packed));
@@ -1429,7 +1432,8 @@
   struct v4l2_format format;
   __u32 capabilities;
   __u32 flags;
-  __u32 reserved[6];
+  __u32 max_num_buffers;
+  __u32 reserved[5];
 };
 #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
 #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index 520a472..021845c 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -14,7 +14,7 @@
 #define VIRTIO_CONFIG_S_NEEDS_RESET 0x40
 #define VIRTIO_CONFIG_S_FAILED 0x80
 #define VIRTIO_TRANSPORT_F_START 28
-#define VIRTIO_TRANSPORT_F_END 41
+#define VIRTIO_TRANSPORT_F_END 42
 #ifndef VIRTIO_CONFIG_NO_LEGACY
 #define VIRTIO_F_NOTIFY_ON_EMPTY 24
 #define VIRTIO_F_ANY_LAYOUT 27
@@ -29,4 +29,5 @@
 #define VIRTIO_F_NOTIFICATION_DATA 38
 #define VIRTIO_F_NOTIF_CONFIG_DATA 39
 #define VIRTIO_F_RING_RESET 40
+#define VIRTIO_F_ADMIN_VQ 41
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_pci.h b/libc/kernel/uapi/linux/virtio_pci.h
index f9595bc..013548c 100644
--- a/libc/kernel/uapi/linux/virtio_pci.h
+++ b/libc/kernel/uapi/linux/virtio_pci.h
@@ -78,6 +78,8 @@
   struct virtio_pci_common_cfg cfg;
   __le16 queue_notify_data;
   __le16 queue_reset;
+  __le16 admin_queue_index;
+  __le16 admin_queue_num;
 };
 struct virtio_pci_cfg_cap {
   struct virtio_pci_cap cap;
@@ -112,5 +114,48 @@
 #define VIRTIO_PCI_COMMON_Q_USEDHI 52
 #define VIRTIO_PCI_COMMON_Q_NDATA 56
 #define VIRTIO_PCI_COMMON_Q_RESET 58
+#define VIRTIO_PCI_COMMON_ADM_Q_IDX 60
+#define VIRTIO_PCI_COMMON_ADM_Q_NUM 62
 #endif
+#define VIRTIO_ADMIN_STATUS_OK 0
+#define VIRTIO_ADMIN_CMD_LIST_QUERY 0x0
+#define VIRTIO_ADMIN_CMD_LIST_USE 0x1
+#define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1
+#define VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_WRITE 0x2
+#define VIRTIO_ADMIN_CMD_LEGACY_COMMON_CFG_READ 0x3
+#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_WRITE 0x4
+#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5
+#define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6
+struct __attribute__((__packed__)) virtio_admin_cmd_hdr {
+  __le16 opcode;
+  __le16 group_type;
+  __u8 reserved1[12];
+  __le64 group_member_id;
+};
+struct __attribute__((__packed__)) virtio_admin_cmd_status {
+  __le16 status;
+  __le16 status_qualifier;
+  __u8 reserved2[4];
+};
+struct __attribute__((__packed__)) virtio_admin_cmd_legacy_wr_data {
+  __u8 offset;
+  __u8 reserved[7];
+  __u8 registers[];
+};
+struct __attribute__((__packed__)) virtio_admin_cmd_legacy_rd_data {
+  __u8 offset;
+};
+#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_END 0
+#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_DEV 0x1
+#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_MEM 0x2
+#define VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO 4
+struct __attribute__((__packed__)) virtio_admin_cmd_notify_info_data {
+  __u8 flags;
+  __u8 bar;
+  __u8 padding[6];
+  __le64 offset;
+};
+struct virtio_admin_cmd_notify_info_result {
+  struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO];
+};
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_pmem.h b/libc/kernel/uapi/linux/virtio_pmem.h
index 182baf7..da0f764 100644
--- a/libc/kernel/uapi/linux/virtio_pmem.h
+++ b/libc/kernel/uapi/linux/virtio_pmem.h
@@ -9,6 +9,8 @@
 #include <linux/types.h>
 #include <linux/virtio_ids.h>
 #include <linux/virtio_config.h>
+#define VIRTIO_PMEM_F_SHMEM_REGION 0
+#define VIRTIO_PMEM_SHMEM_REGION_ID 0
 struct virtio_pmem_config {
   __le64 start;
   __le64 size;
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 86e16a0..3dceafd 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -17,12 +17,20 @@
   BNXT_RE_UCNTX_CMASK_HAVE_MODE = 0x02ULL,
   BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED = 0x04ULL,
   BNXT_RE_UCNTX_CMASK_DBR_PACING_ENABLED = 0x08ULL,
+  BNXT_RE_UCNTX_CMASK_POW2_DISABLED = 0x10ULL,
+  BNXT_RE_COMP_MASK_UCNTX_HW_RETX_ENABLED = 0x40,
 };
 enum bnxt_re_wqe_mode {
   BNXT_QPLIB_WQE_MODE_STATIC = 0x00,
   BNXT_QPLIB_WQE_MODE_VARIABLE = 0x01,
   BNXT_QPLIB_WQE_MODE_INVALID = 0x02,
 };
+enum {
+  BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT = 0x01,
+};
+struct bnxt_re_uctx_req {
+  __aligned_u64 comp_mask;
+};
 struct bnxt_re_uctx_resp {
   __u32 dev_id;
   __u32 max_qp;
@@ -45,11 +53,15 @@
   __aligned_u64 cq_va;
   __aligned_u64 cq_handle;
 };
+enum bnxt_re_cq_mask {
+  BNXT_RE_CQ_TOGGLE_PAGE_SUPPORT = 0x1,
+};
 struct bnxt_re_cq_resp {
   __u32 cqid;
   __u32 tail;
   __u32 phase;
   __u32 rsvd;
+  __aligned_u64 comp_mask;
 };
 struct bnxt_re_resize_cq_req {
   __aligned_u64 cq_va;
@@ -79,6 +91,7 @@
 enum bnxt_re_objects {
   BNXT_RE_OBJECT_ALLOC_PAGE = (1U << UVERBS_ID_NS_SHIFT),
   BNXT_RE_OBJECT_NOTIFY_DRV,
+  BNXT_RE_OBJECT_GET_TOGGLE_MEM,
 };
 enum bnxt_re_alloc_page_type {
   BNXT_RE_ALLOC_WC_PAGE = 0,
@@ -102,4 +115,23 @@
 enum bnxt_re_notify_drv_methods {
   BNXT_RE_METHOD_NOTIFY_DRV = (1U << UVERBS_ID_NS_SHIFT),
 };
+enum bnxt_re_get_toggle_mem_type {
+  BNXT_RE_CQ_TOGGLE_MEM = 0,
+  BNXT_RE_SRQ_TOGGLE_MEM,
+};
+enum bnxt_re_var_toggle_mem_attrs {
+  BNXT_RE_TOGGLE_MEM_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  BNXT_RE_TOGGLE_MEM_TYPE,
+  BNXT_RE_TOGGLE_MEM_RES_ID,
+  BNXT_RE_TOGGLE_MEM_MMAP_PAGE,
+  BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
+  BNXT_RE_TOGGLE_MEM_MMAP_LENGTH,
+};
+enum bnxt_re_toggle_mem_attrs {
+  BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+enum bnxt_re_toggle_mem_methods {
+  BNXT_RE_METHOD_GET_TOGGLE_MEM = (1U << UVERBS_ID_NS_SHIFT),
+  BNXT_RE_METHOD_RELEASE_TOGGLE_MEM,
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h
index c327764..2b30941 100644
--- a/libc/kernel/uapi/rdma/efa-abi.h
+++ b/libc/kernel/uapi/rdma/efa-abi.h
@@ -7,6 +7,7 @@
 #ifndef EFA_ABI_USER_H
 #define EFA_ABI_USER_H
 #include <linux/types.h>
+#include <rdma/ib_user_ioctl_cmds.h>
 #define EFA_UVERBS_ABI_VERSION 1
 enum {
   EFA_ALLOC_UCONTEXT_CMD_COMP_TX_BATCH = 1 << 0,
@@ -104,4 +105,19 @@
   __u32 max_rdma_size;
   __u32 device_caps;
 };
+enum {
+  EFA_QUERY_MR_VALIDITY_RECV_IC_ID = 1 << 0,
+  EFA_QUERY_MR_VALIDITY_RDMA_READ_IC_ID = 1 << 1,
+  EFA_QUERY_MR_VALIDITY_RDMA_RECV_IC_ID = 1 << 2,
+};
+enum efa_query_mr_attrs {
+  EFA_IB_ATTR_QUERY_MR_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+  EFA_IB_ATTR_QUERY_MR_RESP_IC_ID_VALIDITY,
+  EFA_IB_ATTR_QUERY_MR_RESP_RECV_IC_ID,
+  EFA_IB_ATTR_QUERY_MR_RESP_RDMA_READ_IC_ID,
+  EFA_IB_ATTR_QUERY_MR_RESP_RDMA_RECV_IC_ID,
+};
+enum efa_mr_methods {
+  EFA_IB_METHOD_MR_QUERY = (1U << UVERBS_ID_NS_SHIFT),
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index f9effb3..54a5672 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -81,4 +81,8 @@
 struct hns_roce_ib_alloc_pd_resp {
   __u32 pdn;
 };
+struct hns_roce_ib_create_ah_resp {
+  __u8 dmac[6];
+  __u8 reserved[2];
+};
 #endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index dc6420b..22cf99e 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 #include <rdma/ib_user_ioctl_verbs.h>
+#include <rdma/mlx5_user_ioctl_verbs.h>
 enum {
   MLX5_QP_FLAG_SIGNATURE = 1 << 0,
   MLX5_QP_FLAG_SCATTER_CQE = 1 << 1,
@@ -186,6 +187,7 @@
   __u32 tunnel_offloads_caps;
   struct mlx5_ib_dci_streams_caps dci_streams_caps;
   __u16 reserved;
+  struct mlx5_ib_uapi_reg reg_c0;
 };
 enum mlx5_ib_create_cq_flags {
   MLX5_IB_CREATE_CQ_FLAGS_CQE_128B_PAD = 1 << 0,
diff --git a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
index 57fc43e..f087ee8 100644
--- a/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/libc/kernel/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -32,6 +32,7 @@
   MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM,
   MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM,
   MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM,
+  MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM,
 };
 enum mlx5_ib_uapi_devx_create_event_channel_flags {
   MLX5_IB_UAPI_DEVX_CR_EV_CH_FLAGS_OMIT_DATA = 1 << 0,
diff --git a/libc/kernel/uapi/regulator/regulator.h b/libc/kernel/uapi/regulator/regulator.h
new file mode 100644
index 0000000..23ce7c6
--- /dev/null
+++ b/libc/kernel/uapi/regulator/regulator.h
@@ -0,0 +1,47 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_REGULATOR_H
+#define _UAPI_REGULATOR_H
+#include <stdint.h>
+#define REGULATOR_EVENT_UNDER_VOLTAGE 0x01
+#define REGULATOR_EVENT_OVER_CURRENT 0x02
+#define REGULATOR_EVENT_REGULATION_OUT 0x04
+#define REGULATOR_EVENT_FAIL 0x08
+#define REGULATOR_EVENT_OVER_TEMP 0x10
+#define REGULATOR_EVENT_FORCE_DISABLE 0x20
+#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
+#define REGULATOR_EVENT_DISABLE 0x80
+#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
+#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
+#define REGULATOR_EVENT_PRE_DISABLE 0x400
+#define REGULATOR_EVENT_ABORT_DISABLE 0x800
+#define REGULATOR_EVENT_ENABLE 0x1000
+#define REGULATOR_EVENT_UNDER_VOLTAGE_WARN 0x2000
+#define REGULATOR_EVENT_OVER_CURRENT_WARN 0x4000
+#define REGULATOR_EVENT_OVER_VOLTAGE_WARN 0x8000
+#define REGULATOR_EVENT_OVER_TEMP_WARN 0x10000
+#define REGULATOR_EVENT_WARN_MASK 0x1E000
+struct reg_genl_event {
+  char reg_name[32];
+  uint64_t event;
+};
+enum {
+  REG_GENL_ATTR_UNSPEC,
+  REG_GENL_ATTR_EVENT,
+  __REG_GENL_ATTR_MAX,
+};
+#define REG_GENL_ATTR_MAX (__REG_GENL_ATTR_MAX - 1)
+enum {
+  REG_GENL_CMD_UNSPEC,
+  REG_GENL_CMD_EVENT,
+  __REG_GENL_CMD_MAX,
+};
+#define REG_GENL_CMD_MAX (__REG_GENL_CMD_MAX - 1)
+#define REG_GENL_FAMILY_NAME "reg_event"
+#define REG_GENL_VERSION 0x01
+#define REG_GENL_MCAST_GROUP_NAME "reg_mc_group"
+#endif
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
index f12c36f..bac5017 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -242,6 +242,8 @@
 #define MPI3MR_NVME_DATA_FORMAT_PRP 0
 #define MPI3MR_NVME_DATA_FORMAT_SGL1 1
 #define MPI3MR_NVME_DATA_FORMAT_SGL2 2
+#define MPI3MR_NVMESGL_DATA_SEGMENT 0x00
+#define MPI3MR_NVMESGL_LAST_SEGMENT 0x03
 struct mpi3_scsi_task_mgmt_request {
   __le16 host_tag;
   __u8 ioc_use_only02;
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index 7da2fbb..b608ed5 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -92,7 +92,7 @@
 #define SNDRV_HWDEP_IOCTL_INFO _IOR('H', 0x01, struct snd_hwdep_info)
 #define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status)
 #define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image)
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 17)
 typedef unsigned long snd_pcm_uframes_t;
 typedef signed long snd_pcm_sframes_t;
 enum {
@@ -201,7 +201,10 @@
 #endif
 typedef int __bitwise snd_pcm_subformat_t;
 #define SNDRV_PCM_SUBFORMAT_STD (( snd_pcm_subformat_t) 0)
-#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD
+#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX (( snd_pcm_subformat_t) 1)
+#define SNDRV_PCM_SUBFORMAT_MSBITS_20 (( snd_pcm_subformat_t) 2)
+#define SNDRV_PCM_SUBFORMAT_MSBITS_24 (( snd_pcm_subformat_t) 3)
+#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_MSBITS_24
 #define SNDRV_PCM_INFO_MMAP 0x00000001
 #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
 #define SNDRV_PCM_INFO_DOUBLE 0x00000004
diff --git a/libc/kernel/uapi/sound/scarlett2.h b/libc/kernel/uapi/sound/scarlett2.h
new file mode 100644
index 0000000..13e6abe
--- /dev/null
+++ b/libc/kernel/uapi/sound/scarlett2.h
@@ -0,0 +1,30 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef __UAPI_SOUND_SCARLETT2_H
+#define __UAPI_SOUND_SCARLETT2_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define SCARLETT2_HWDEP_MAJOR 1
+#define SCARLETT2_HWDEP_MINOR 0
+#define SCARLETT2_HWDEP_SUBMINOR 0
+#define SCARLETT2_HWDEP_VERSION ((SCARLETT2_HWDEP_MAJOR << 16) | (SCARLETT2_HWDEP_MINOR << 8) | SCARLETT2_HWDEP_SUBMINOR)
+#define SCARLETT2_HWDEP_VERSION_MAJOR(v) (((v) >> 16) & 0xFF)
+#define SCARLETT2_HWDEP_VERSION_MINOR(v) (((v) >> 8) & 0xFF)
+#define SCARLETT2_HWDEP_VERSION_SUBMINOR(v) ((v) & 0xFF)
+#define SCARLETT2_IOCTL_PVERSION _IOR('S', 0x60, int)
+#define SCARLETT2_IOCTL_REBOOT _IO('S', 0x61)
+#define SCARLETT2_SEGMENT_ID_SETTINGS 0
+#define SCARLETT2_SEGMENT_ID_FIRMWARE 1
+#define SCARLETT2_SEGMENT_ID_COUNT 2
+#define SCARLETT2_IOCTL_SELECT_FLASH_SEGMENT _IOW('S', 0x62, int)
+#define SCARLETT2_IOCTL_ERASE_FLASH_SEGMENT _IO('S', 0x63)
+struct scarlett2_flash_segment_erase_progress {
+  unsigned char progress;
+  unsigned char num_blocks;
+};
+#define SCARLETT2_IOCTL_GET_ERASE_PROGRESS _IOR('S', 0x64, struct scarlett2_flash_segment_erase_progress)
+#endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index d57d55b..b55a895 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -15,6 +15,7 @@
 #define SOF_TPLG_KCTL_BYTES_WO_ID 262
 #define SOF_TKN_BUF_SIZE 100
 #define SOF_TKN_BUF_CAPS 101
+#define SOF_TKN_BUF_FLAGS 102
 #define SOF_TKN_DAI_TYPE 154
 #define SOF_TKN_DAI_INDEX 155
 #define SOF_TKN_DAI_DIRECTION 156
@@ -125,4 +126,6 @@
 #define SOF_TKN_AMD_ACPI2S_RATE 1700
 #define SOF_TKN_AMD_ACPI2S_CH 1701
 #define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
+#define SOF_TKN_IMX_MICFIL_RATE 2000
+#define SOF_TKN_IMX_MICFIL_CH 2001
 #endif
diff --git a/libc/kernel/uapi/xen/gntalloc.h b/libc/kernel/uapi/xen/gntalloc.h
index 02e4d47..4f0e7b8 100644
--- a/libc/kernel/uapi/xen/gntalloc.h
+++ b/libc/kernel/uapi/xen/gntalloc.h
@@ -13,7 +13,10 @@
   __u16 flags;
   __u32 count;
   __u64 index;
-  __u32 gref_ids[1];
+  union {
+    __u32 gref_ids[1];
+    __DECLARE_FLEX_ARRAY(__u32, gref_ids_flex);
+  };
 };
 #define GNTALLOC_FLAG_WRITABLE 1
 #define IOCTL_GNTALLOC_DEALLOC_GREF _IOC(_IOC_NONE, 'G', 6, sizeof(struct ioctl_gntalloc_dealloc_gref))
diff --git a/libc/malloc_debug/MapData.cpp b/libc/malloc_debug/MapData.cpp
index b22c109..c58882a 100644
--- a/libc/malloc_debug/MapData.cpp
+++ b/libc/malloc_debug/MapData.cpp
@@ -34,6 +34,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/uio.h>
+#include <unistd.h>
 
 #include <vector>
 
@@ -69,148 +71,132 @@
 
   MapEntry* entry = new MapEntry(start, end, offset, name, name_len, flags);
   if (!(flags & PROT_READ)) {
-    // Any unreadable map will just get a zero load bias.
-    entry->load_bias = 0;
-    entry->init = true;
-    entry->valid = false;
+    // This will make sure that an unreadable map will prevent attempts to read
+    // elf data from the map.
+    entry->SetInvalid();
   }
   return entry;
 }
 
-template <typename T>
-static inline bool get_val(MapEntry* entry, uintptr_t addr, T* store) {
-  if (!(entry->flags & PROT_READ) || addr < entry->start || addr + sizeof(T) > entry->end) {
-    return false;
+void MapEntry::Init() {
+  if (init_) {
+    return;
   }
-  // Make sure the address is aligned properly.
-  if (addr & (sizeof(T) - 1)) {
-    return false;
-  }
-  *store = *reinterpret_cast<T*>(addr);
-  return true;
-}
+  init_ = true;
 
-static bool valid_elf(MapEntry* entry) {
-  uintptr_t addr = entry->start;
-  uintptr_t end;
-  if (__builtin_add_overflow(addr, SELFMAG, &end) || end >= entry->end) {
-    return false;
+  uintptr_t end_addr;
+  if (__builtin_add_overflow(start_, SELFMAG, &end_addr) || end_addr >= end_) {
+    return;
   }
 
-  return memcmp(reinterpret_cast<void*>(addr), ELFMAG, SELFMAG) == 0;
-}
-
-static void read_loadbias(MapEntry* entry) {
-  entry->load_bias = 0;
-  uintptr_t addr = entry->start;
   ElfW(Ehdr) ehdr;
-  if (!get_val<ElfW(Half)>(entry, addr + offsetof(ElfW(Ehdr), e_phnum), &ehdr.e_phnum)) {
-    return;
+  struct iovec src_io = {.iov_base = reinterpret_cast<void*>(start_), .iov_len = SELFMAG};
+  struct iovec dst_io = {.iov_base = ehdr.e_ident, .iov_len = SELFMAG};
+  ssize_t rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+  valid_ = rc == SELFMAG && IS_ELF(ehdr);
+}
+
+uintptr_t MapEntry::GetLoadBias() {
+  if (!valid_) {
+    return 0;
   }
-  if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Ehdr), e_phoff), &ehdr.e_phoff)) {
-    return;
+
+  if (load_bias_read_) {
+    return load_bias_;
   }
-  addr += ehdr.e_phoff;
+
+  load_bias_read_ = true;
+
+  ElfW(Ehdr) ehdr;
+  struct iovec src_io = {.iov_base = reinterpret_cast<void*>(start_), .iov_len = sizeof(ehdr)};
+  struct iovec dst_io = {.iov_base = &ehdr, .iov_len = sizeof(ehdr)};
+  ssize_t rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+  if (rc != sizeof(ehdr)) {
+    return 0;
+  }
+
+  uintptr_t addr = start_ + ehdr.e_phoff;
   for (size_t i = 0; i < ehdr.e_phnum; i++) {
     ElfW(Phdr) phdr;
-    if (!get_val<ElfW(Word)>(entry, addr + offsetof(ElfW(Phdr), p_type), &phdr.p_type)) {
-      return;
-    }
-    if (!get_val<ElfW(Word)>(entry, addr + offsetof(ElfW(Phdr), p_flags), &phdr.p_flags)) {
-      return;
-    }
-    if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Phdr), p_offset), &phdr.p_offset)) {
-      return;
+
+    src_io.iov_base = reinterpret_cast<void*>(addr);
+    src_io.iov_len = sizeof(phdr);
+    dst_io.iov_base = &phdr;
+    dst_io.iov_len = sizeof(phdr);
+    rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+    if (rc != sizeof(phdr)) {
+      return 0;
     }
     if ((phdr.p_type == PT_LOAD) && (phdr.p_flags & PF_X) ) {
-      if (!get_val<ElfW(Addr)>(entry, addr + offsetof(ElfW(Phdr), p_vaddr), &phdr.p_vaddr)) {
-        return;
-      }
-      entry->load_bias = phdr.p_vaddr - phdr.p_offset;
-      return;
+      load_bias_ = phdr.p_vaddr - phdr.p_offset;
+      return load_bias_;
     }
     addr += sizeof(phdr);
   }
+  return 0;
 }
 
-static void inline init(MapEntry* entry) {
-  if (entry->init) {
-    return;
-  }
-  entry->init = true;
-  if (valid_elf(entry)) {
-    entry->valid = true;
-    read_loadbias(entry);
-  }
-}
-
-bool MapData::ReadMaps() {
+void MapData::ReadMaps() {
+  std::lock_guard<std::mutex> lock(m_);
   FILE* fp = fopen("/proc/self/maps", "re");
   if (fp == nullptr) {
-    return false;
+    return;
   }
 
+  ClearEntries();
+
   std::vector<char> buffer(1024);
   while (fgets(buffer.data(), buffer.size(), fp) != nullptr) {
     MapEntry* entry = parse_line(buffer.data());
     if (entry == nullptr) {
-      fclose(fp);
-      return false;
+      break;
     }
-
-    auto it = entries_.find(entry);
-    if (it == entries_.end()) {
-      entries_.insert(entry);
-    } else {
-      delete entry;
-    }
+    entries_.insert(entry);
   }
   fclose(fp);
-  return true;
 }
 
-MapData::~MapData() {
+void MapData::ClearEntries() {
   for (auto* entry : entries_) {
     delete entry;
   }
   entries_.clear();
 }
 
+MapData::~MapData() {
+  ClearEntries();
+}
+
 // Find the containing map info for the PC.
 const MapEntry* MapData::find(uintptr_t pc, uintptr_t* rel_pc) {
   MapEntry pc_entry(pc);
 
   std::lock_guard<std::mutex> lock(m_);
-
   auto it = entries_.find(&pc_entry);
   if (it == entries_.end()) {
-    ReadMaps();
-  }
-  it = entries_.find(&pc_entry);
-  if (it == entries_.end()) {
     return nullptr;
   }
 
   MapEntry* entry = *it;
-  init(entry);
+  entry->Init();
 
   if (rel_pc != nullptr) {
     // Need to check to see if this is a read-execute map and the read-only
     // map is the previous one.
-    if (!entry->valid && it != entries_.begin()) {
+    if (!entry->valid() && it != entries_.begin()) {
       MapEntry* prev_entry = *--it;
-      if (prev_entry->flags == PROT_READ && prev_entry->offset < entry->offset &&
-          prev_entry->name == entry->name) {
-        init(prev_entry);
+      if (prev_entry->flags() == PROT_READ && prev_entry->offset() < entry->offset() &&
+          prev_entry->name() == entry->name()) {
+        prev_entry->Init();
 
-        if (prev_entry->valid) {
-          entry->elf_start_offset = prev_entry->offset;
-          *rel_pc = pc - entry->start + entry->offset + prev_entry->load_bias;
+        if (prev_entry->valid()) {
+          entry->set_elf_start_offset(prev_entry->offset());
+          *rel_pc = pc - entry->start() + entry->offset() + prev_entry->GetLoadBias();
           return entry;
         }
       }
     }
-    *rel_pc = pc - entry->start + entry->offset + entry->load_bias;
+    *rel_pc = pc - entry->start() + entry->offset() + entry->GetLoadBias();
   }
   return entry;
 }
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index f2b3c1c..13bf9cb 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -36,26 +36,50 @@
 
 #include <platform/bionic/macros.h>
 
-struct MapEntry {
-  MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len, int flags)
-      : start(start), end(end), offset(offset), name(name, name_len), flags(flags) {}
+class MapEntry {
+ public:
+  MapEntry() = default;
+  MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len,
+           int flags)
+      : start_(start), end_(end), offset_(offset), name_(name, name_len), flags_(flags) {}
 
-  explicit MapEntry(uintptr_t pc) : start(pc), end(pc) {}
+  explicit MapEntry(uintptr_t pc) : start_(pc), end_(pc) {}
 
-  uintptr_t start;
-  uintptr_t end;
-  uintptr_t offset;
-  uintptr_t load_bias;
-  uintptr_t elf_start_offset = 0;
-  std::string name;
-  int flags;
-  bool init = false;
-  bool valid = false;
+  void Init();
+
+  uintptr_t GetLoadBias();
+
+  void SetInvalid() {
+    valid_ = false;
+    init_ = true;
+    load_bias_read_ = true;
+  }
+
+  bool valid() { return valid_; }
+  uintptr_t start() const { return start_; }
+  uintptr_t end() const { return end_; }
+  uintptr_t offset() const { return offset_; }
+  uintptr_t elf_start_offset() const { return elf_start_offset_; }
+  void set_elf_start_offset(uintptr_t elf_start_offset) { elf_start_offset_ = elf_start_offset; }
+  const std::string& name() const { return name_; }
+  int flags() const { return flags_; }
+
+ private:
+  uintptr_t start_;
+  uintptr_t end_;
+  uintptr_t offset_;
+  uintptr_t load_bias_ = 0;
+  uintptr_t elf_start_offset_ = 0;
+  std::string name_;
+  int flags_;
+  bool init_ = false;
+  bool valid_ = false;
+  bool load_bias_read_ = false;
 };
 
 // Ordering comparator that returns equivalence for overlapping entries
 struct compare_entries {
-  bool operator()(const MapEntry* a, const MapEntry* b) const { return a->end <= b->start; }
+  bool operator()(const MapEntry* a, const MapEntry* b) const { return a->end() <= b->start(); }
 };
 
 class MapData {
@@ -65,11 +89,15 @@
 
   const MapEntry* find(uintptr_t pc, uintptr_t* rel_pc = nullptr);
 
- private:
-  bool ReadMaps();
+  size_t NumMaps() { return entries_.size(); }
 
+  void ReadMaps();
+
+ private:
   std::mutex m_;
   std::set<MapEntry*, compare_entries> entries_;
 
+  void ClearEntries();
+
   BIONIC_DISALLOW_COPY_AND_ASSIGN(MapData);
 };
diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp
index ecb3a80..6a32fca 100644
--- a/libc/malloc_debug/backtrace.cpp
+++ b/libc/malloc_debug/backtrace.cpp
@@ -50,7 +50,7 @@
 typedef struct _Unwind_Context __unwind_context;
 
 static MapData g_map_data;
-static const MapEntry* g_current_code_map = nullptr;
+static MapEntry g_current_code_map;
 
 static _Unwind_Reason_Code find_current_map(__unwind_context* context, void*) {
   uintptr_t ip = _Unwind_GetIP(context);
@@ -58,11 +58,15 @@
   if (ip == 0) {
     return _URC_END_OF_STACK;
   }
-  g_current_code_map = g_map_data.find(ip);
+  auto map = g_map_data.find(ip);
+  if (map != nullptr) {
+    g_current_code_map = *map;
+  }
   return _URC_END_OF_STACK;
 }
 
 void backtrace_startup() {
+  g_map_data.ReadMaps();
   _Unwind_Backtrace(find_current_map, nullptr);
 }
 
@@ -98,7 +102,8 @@
   }
 
   // Do not record the frames that fall in our own shared library.
-  if (g_current_code_map && (ip >= g_current_code_map->start) && ip < g_current_code_map->end) {
+  if (g_current_code_map.start() != 0 && (ip >= g_current_code_map.start()) &&
+      ip < g_current_code_map.end()) {
     return _URC_NO_REASON;
   }
 
@@ -113,6 +118,10 @@
 }
 
 std::string backtrace_string(const uintptr_t* frames, size_t frame_count) {
+  if (g_map_data.NumMaps() == 0) {
+    g_map_data.ReadMaps();
+  }
+
   std::string str;
 
   for (size_t frame_num = 0; frame_num < frame_count; frame_num++) {
@@ -130,14 +139,15 @@
     uintptr_t rel_pc = offset;
     const MapEntry* entry = g_map_data.find(frames[frame_num], &rel_pc);
 
-    const char* soname = (entry != nullptr) ? entry->name.c_str() : info.dli_fname;
+    const char* soname = (entry != nullptr) ? entry->name().c_str() : info.dli_fname;
     if (soname == nullptr) {
       soname = "<unknown>";
     }
 
     char offset_buf[128];
-    if (entry != nullptr && entry->elf_start_offset != 0) {
-      snprintf(offset_buf, sizeof(offset_buf), " (offset 0x%" PRIxPTR ")", entry->elf_start_offset);
+    if (entry != nullptr && entry->elf_start_offset() != 0) {
+      snprintf(offset_buf, sizeof(offset_buf), " (offset 0x%" PRIxPTR ")",
+               entry->elf_start_offset());
     } else {
       offset_buf[0] = '\0';
     }
@@ -167,5 +177,6 @@
 }
 
 void backtrace_log(const uintptr_t* frames, size_t frame_count) {
+  g_map_data.ReadMaps();
   error_log_string(backtrace_string(frames, frame_count).c_str());
 }
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 3731a5d..b66b8e2 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -70,7 +70,7 @@
 
 const MallocDispatch* g_dispatch;
 
-static __always_inline uint64_t Nanotime() {
+static inline __always_inline uint64_t Nanotime() {
   struct timespec t = {};
   clock_gettime(CLOCK_MONOTONIC, &t);
   return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h
index a06b8ee..da85cf5 100644
--- a/libc/platform/bionic/malloc.h
+++ b/libc/platform/bionic/malloc.h
@@ -130,32 +130,55 @@
   // Worth noting, the "libc.debug.gwp_asan.*.app_default" sysprops *do not*
   // apply to system apps. They use the "libc.debug.gwp_asan.*.system_default"
   // sysprops.
-  enum Action {
-    // Enable GWP-ASan. This is used by apps that have `gwpAsanMode=always` in
-    // the manifest.
-    TURN_ON_FOR_APP,
-    // Enable GWP-ASan, but only a small percentage of the time. This is used by
-    // system processes and system apps, and we use a lottery to determine which
-    // processes have GWP-ASan enabled. This allows us to mitigate system-wide
-    // memory overhead concerns, as each GWP-ASan enabled process uses ~70KiB of
-    // extra memory.
-    TURN_ON_WITH_SAMPLING,
-    // Don't enable GWP-ASan, unless overwritten by a system property or
-    // environment variable. This is used by apps that have `gwpAsanMode=never`
-    // in the manifest. Prior to Android 14, this also was used by non-system
-    // apps that didn't specify a `gwpAsanMode` in their manifest.
-    DONT_TURN_ON_UNLESS_OVERRIDDEN,
-    // Enable GWP-ASan, but only a small percentage of the time, and enable it
-    // in the non-crashing ("recoverable") mode. In Android 14, this is used by
-    // apps that don't specify `gwpAsanMode` (or use `gwpAsanMode=default`) in
-    // their manifest. GWP-ASan will detect heap memory safety bugs in this
-    // mode, and bug reports will be created by debuggerd, however the process
-    // will recover and continue to function as if the memory safety bug wasn't
-    // detected.
-    TURN_ON_FOR_APP_SAMPLED_NON_CRASHING,
+  //
+  // In recoverable mode, GWP-ASan will detect heap memory safety bugs, and bug
+  // reports will be created by debuggerd, however the process will recover and
+  // continue to function as if the memory safety bug wasn't detected. This
+  // prevents any user-visible impact as apps and processes don't crash, and
+  // probably saves us some CPU time in restarting the process.
+  //
+  // Process sampling enables GWP-ASan, but only a small percentage of the time
+  // (~1%). This helps mitigate any recurring high-frequency problems in certain
+  // processes, as it's highly likely the next restart of said process won't
+  // have GWP-ASan. In addition, for system processes and system apps, this
+  // allows us to mitigate system-wide memory overhead concerns, as each
+  // GWP-ASan enabled process uses ~70KiB of extra memory.
+  enum Mode {
+    // Used by default for apps, or by those that have an explicit
+    // `gwpAsanMode=default` in the manifest.
+    //
+    // Result:
+    //  - Android 13 and before: GWP-ASan is not enabled.
+    //  - Android 14 and after: Enables GWP-ASan with process sampling in
+    //    recoverable mode.
+    APP_MANIFEST_DEFAULT = 3,
+    // This is used by apps that have `gwpAsanMode=always` in the manifest.
+    //
+    // Result:
+    //  - Android 14 and before: Enables GWP-ASan in non-recoverable mode,
+    //    without process sampling.
+    //  - Android 15 and after: Enables GWP-ASan in recoverable mode, without
+    //    process sampling.
+    APP_MANIFEST_ALWAYS = 0,
+    // This is used by apps that have `gwpAsanMode=never` in the manifest.
+    //
+    // Result:
+    //  - GWP-ASan is not enabled, unless it's force-enabled by a system
+    //    property or environment variable.
+    APP_MANIFEST_NEVER = 2,
+    // Used by system processes and system apps.
+    //
+    // Result:
+    //  - Android 14 and before: Enables GWP-ASan with process sampling in
+    //    non-recoverable mode.
+    //  - Android 15 and after: Enables GWP-ASan with process sampling in
+    //    recoverable mode.
+    SYSTEM_PROCESS_OR_SYSTEM_APP = 1,
+    // Next enum value = 4. Numbered non-sequentially above to preserve ABI
+    // stability, but now ordered more logically.
   };
 
-  Action desire = DONT_TURN_ON_UNLESS_OVERRIDDEN;
+  Mode mode = APP_MANIFEST_NEVER;
 } android_mallopt_gwp_asan_options_t;
 #pragma clang diagnostic pop
 // Manipulates bionic-specific handling of memory allocation APIs such as
diff --git a/libc/platform/bionic/page.h b/libc/platform/bionic/page.h
index 65faba4..4dbe4ba 100644
--- a/libc/platform/bionic/page.h
+++ b/libc/platform/bionic/page.h
@@ -32,11 +32,13 @@
 #endif
 }
 
-constexpr size_t max_page_size() {
+// The maximum page size supported on any Android device. As
+// of API level 35, this is limited by ART.
+constexpr size_t max_android_page_size() {
 #if defined(PAGE_SIZE)
   return PAGE_SIZE;
 #else
-  return 65536;
+  return 16384;
 #endif
 }
 
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index fac07cb..f269125 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -30,11 +30,11 @@
 template <typename T>
 union WriteProtectedContents {
   T value;
-  char padding[max_page_size()];
+  char padding[max_android_page_size()];
 
   WriteProtectedContents() = default;
   BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
-} __attribute__((aligned(max_page_size())));
+} __attribute__((aligned(max_android_page_size())));
 
 // Write protected wrapper class that aligns its contents to a page boundary,
 // and sets the memory protection to be non-writable, except when being modified
@@ -42,8 +42,8 @@
 template <typename T>
 class WriteProtected {
  public:
-  static_assert(sizeof(T) < max_page_size(),
-                "WriteProtected only supports contents up to max_page_size()");
+  static_assert(sizeof(T) < max_android_page_size(),
+                "WriteProtected only supports contents up to max_android_page_size()");
 
   WriteProtected() = default;
   BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
@@ -51,36 +51,45 @@
   void initialize() {
     // Not strictly necessary, but this will hopefully segfault if we initialize
     // multiple times by accident.
-    memset(&contents, 0, sizeof(contents));
+    memset(contents_addr(), 0, sizeof(contents));
     set_protection(PROT_READ);
   }
 
   const T* operator->() {
-    return &contents.value;
+    return &contents_addr()->value;
   }
 
   const T& operator*() {
-    return contents.value;
+    return contents_addr()->value;
   }
 
   template <typename Mutator>
   void mutate(Mutator mutator) {
     set_protection(PROT_READ | PROT_WRITE);
-    mutator(&contents.value);
+    mutator(&contents_addr()->value);
     set_protection(PROT_READ);
   }
 
  private:
   WriteProtectedContents<T> contents;
 
-  void set_protection(int prot) {
+  WriteProtectedContents<T>* contents_addr() {
     auto addr = &contents;
+    // Hide the fact that we're returning the address of contents from the compiler.
+    // Otherwise it may generate code assuming alignment of 64KB even though the
+    // variable is only guaranteed to have 4KB alignment.
+    __asm__ __volatile__("" : "+r"(addr));
+    return addr;
+  }
+
+  void set_protection(int prot) {
+    auto addr = contents_addr();
 #if __has_feature(hwaddress_sanitizer)
     // The mprotect system call does not currently untag pointers, so do it
     // ourselves.
     addr = untag_address(addr);
 #endif
-    if (mprotect(reinterpret_cast<void*>(addr), max_page_size(), prot) == -1) {
+    if (mprotect(reinterpret_cast<void*>(addr), max_android_page_size(), prot) == -1) {
       async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
     }
   }
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
index 9dd5e35..e0d38a8 100644
--- a/libc/system_properties/system_properties.cpp
+++ b/libc/system_properties/system_properties.cpp
@@ -120,14 +120,18 @@
     return false;
   }
 
-  auto* appcompat_contexts = new (appcompat_override_contexts_data_) ContextsSerialized();
   appcompat_filename_ = PropertiesFilename(properties_filename_.c_str(), "appcompat_override");
-  if (!appcompat_contexts->Initialize(true, appcompat_filename_.c_str(), fsetxattr_failed,
-                                      load_default_path)) {
-    appcompat_override_contexts_ = nullptr;
-    return false;
+  appcompat_override_contexts_ = nullptr;
+  if (access(appcompat_filename_.c_str(), F_OK) != -1) {
+    auto* appcompat_contexts = new (appcompat_override_contexts_data_) ContextsSerialized();
+    if (!appcompat_contexts->Initialize(true, appcompat_filename_.c_str(), fsetxattr_failed,
+                                        load_default_path)) {
+      // The appcompat folder exists, but initializing it failed
+      return false;
+    } else {
+      appcompat_override_contexts_ = appcompat_contexts;
+    }
   }
-  appcompat_override_contexts_ = appcompat_contexts;
 
   initialized_ = true;
   return true;
@@ -333,31 +337,42 @@
 
 int SystemProperties::Add(const char* name, unsigned int namelen, const char* value,
                           unsigned int valuelen) {
-  if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) {
+  if (namelen < 1) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: name length 0");
     return -1;
   }
 
-  if (namelen < 1) {
+  if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: \"%s\" value too long: %d >= PROP_VALUE_MAX",
+                          name, valuelen);
     return -1;
   }
 
   if (!initialized_) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: properties not initialized");
     return -1;
   }
 
   prop_area* serial_pa = contexts_->GetSerialPropArea();
   if (serial_pa == nullptr) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: property area not found");
     return -1;
   }
 
   prop_area* pa = contexts_->GetPropAreaForName(name);
   if (!pa) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: access denied for \"%s\"", name);
     return -1;
   }
 
-  bool ret = pa->add(name, namelen, value, valuelen);
-  if (!ret) {
+  if (!pa->add(name, namelen, value, valuelen)) {
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                          "__system_property_add failed: add failed for \"%s\"", name);
     return -1;
   }
 
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index 8e6f87d..cbc52b5 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -42,23 +42,8 @@
 
 #define PROTO_NORMAL(x)
 
-/* OpenBSD's <ctype.h> uses these names, which conflicted with stlport.
- * Additionally, we changed the numeric/digit type from N to D for libcxx.
- */
-#define _U _CTYPE_U
-#define _L _CTYPE_L
-#define _N _CTYPE_D
-#define _S _CTYPE_S
-#define _P _CTYPE_P
-#define _C _CTYPE_C
-#define _X _CTYPE_X
-#define _B _CTYPE_B
-
-/* OpenBSD has this, but we can't really implement it correctly on Linux. */
-#define issetugid() 0
-
 #if !defined(ANDROID_HOST_MUSL)
-#define explicit_bzero(p, s) memset(p, 0, s)
+#define explicit_bzero(p, s) memset_explicit(p, 0, s)
 #endif
 
 #if defined(ANDROID_HOST_MUSL)
diff --git a/libc/upstream-openbsd/lib/libc/crypt/arc4random.c b/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
index 8a4ecc9..0737cf3 100644
--- a/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
+++ b/libc/upstream-openbsd/lib/libc/crypt/arc4random.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $	*/
+/*	$OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $	*/
 
 /*
  * Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -49,6 +49,8 @@
 #define BLOCKSZ	64
 #define RSBUFSZ	(16*BLOCKSZ)
 
+#define REKEY_BASE	(1024*1024) /* NB. should be a power of 2 */
+
 /* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
 static struct _rs {
 	size_t		rs_have;	/* valid bytes at end of rs_buf */
@@ -78,7 +80,7 @@
 			abort();
 	}
 
-	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
+	chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8);
 	chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
 }
 
@@ -86,6 +88,7 @@
 _rs_stir(void)
 {
 	u_char rnd[KEYSZ + IVSZ];
+	uint32_t rekey_fuzz = 0;
 
 	if (getentropy(rnd, sizeof rnd) == -1)
 		_getentropy_fail();
@@ -100,7 +103,10 @@
 	rs->rs_have = 0;
 	memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
 
-	rs->rs_count = 1600000;
+	/* rekey interval should not be predictable */
+	chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
+	    (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
+	rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
 }
 
 static inline void
diff --git a/libc/upstream-openbsd/lib/libc/crypt/chacha_private.h b/libc/upstream-openbsd/lib/libc/crypt/chacha_private.h
index 7c3680f..b0427b6 100644
--- a/libc/upstream-openbsd/lib/libc/crypt/chacha_private.h
+++ b/libc/upstream-openbsd/lib/libc/crypt/chacha_private.h
@@ -4,7 +4,7 @@
 Public domain.
 */
 
-/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
+/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */
 
 typedef unsigned char u8;
 typedef unsigned int u32;
@@ -52,7 +52,7 @@
 static const char tau[16] = "expand 16-byte k";
 
 static void
-chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ivbits)
+chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits)
 {
   const char *constants;
 
diff --git a/libc/upstream-openbsd/lib/libc/gen/ctype_.c b/libc/upstream-openbsd/lib/libc/gen/ctype_.c
index 8972244..9742c9f 100644
--- a/libc/upstream-openbsd/lib/libc/gen/ctype_.c
+++ b/libc/upstream-openbsd/lib/libc/gen/ctype_.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: ctype_.c,v 1.12 2015/09/19 04:02:21 guenther Exp $ */
+/*	$OpenBSD: ctype_.c,v 1.13 2024/02/04 13:03:18 jca Exp $ */
 /*
  * Copyright (c) 1989 The Regents of the University of California.
  * All rights reserved.
@@ -36,6 +36,16 @@
 #include <ctype.h>
 #include "ctype_private.h"
 
+/* Shorter names for the defines provided by <ctype.h> */
+#define	_U	_CTYPE_U
+#define	_L	_CTYPE_L
+#define	_N	_CTYPE_N
+#define	_S	_CTYPE_S
+#define	_P	_CTYPE_P
+#define	_C	_CTYPE_C
+#define	_X	_CTYPE_X
+#define	_B	_CTYPE_B
+
 const char _C_ctype_[1 + CTYPE_NUM_CHARS] = {
 	0,
 	_C,	_C,	_C,	_C,	_C,	_C,	_C,	_C,
diff --git a/libc/upstream-openbsd/lib/libc/net/htonl.c b/libc/upstream-openbsd/lib/libc/net/htonl.c
index 6ee6e7e..58bfb46 100644
--- a/libc/upstream-openbsd/lib/libc/net/htonl.c
+++ b/libc/upstream-openbsd/lib/libc/net/htonl.c
@@ -1,6 +1,5 @@
-/*	$OpenBSD: htonl.c,v 1.7 2014/07/21 01:51:10 guenther Exp $ */
+/*	$OpenBSD: htonl.c,v 1.8 2024/04/15 14:30:48 naddy Exp $ */
 /*
- * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
  */
 
@@ -9,13 +8,8 @@
 
 #undef htonl
 
-u_int32_t
-htonl(u_int32_t x)
+uint32_t
+htonl(uint32_t x)
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-	u_char *s = (u_char *)&x;
-	return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
-#else
-	return x;
-#endif
+	return htobe32(x);
 }
diff --git a/libc/upstream-openbsd/lib/libc/net/htons.c b/libc/upstream-openbsd/lib/libc/net/htons.c
index f48d91e..28b13ce 100644
--- a/libc/upstream-openbsd/lib/libc/net/htons.c
+++ b/libc/upstream-openbsd/lib/libc/net/htons.c
@@ -1,6 +1,5 @@
-/*	$OpenBSD: htons.c,v 1.9 2014/07/21 01:51:10 guenther Exp $ */
+/*	$OpenBSD: htons.c,v 1.10 2024/04/15 14:30:48 naddy Exp $ */
 /*
- * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
  */
 
@@ -9,13 +8,8 @@
 
 #undef htons
 
-u_int16_t
-htons(u_int16_t x)
+uint16_t
+htons(uint16_t x)
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-	u_char *s = (u_char *) &x;
-	return (u_int16_t)(s[0] << 8 | s[1]);
-#else
-	return x;
-#endif
+	return htobe16(x);
 }
diff --git a/libc/upstream-openbsd/lib/libc/net/ntohl.c b/libc/upstream-openbsd/lib/libc/net/ntohl.c
index 0d05bac..7592398 100644
--- a/libc/upstream-openbsd/lib/libc/net/ntohl.c
+++ b/libc/upstream-openbsd/lib/libc/net/ntohl.c
@@ -1,6 +1,5 @@
-/*	$OpenBSD: ntohl.c,v 1.7 2014/07/21 01:51:10 guenther Exp $ */
+/*	$OpenBSD: ntohl.c,v 1.8 2024/04/15 14:30:48 naddy Exp $ */
 /*
- * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
  */
 
@@ -9,13 +8,8 @@
 
 #undef ntohl
 
-u_int32_t
-ntohl(u_int32_t x)
+uint32_t
+ntohl(uint32_t x)
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-	u_char *s = (u_char *)&x;
-	return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
-#else
-	return x;
-#endif
+	return be32toh(x);
 }
diff --git a/libc/upstream-openbsd/lib/libc/net/ntohs.c b/libc/upstream-openbsd/lib/libc/net/ntohs.c
index b5ea361..ef22ea3 100644
--- a/libc/upstream-openbsd/lib/libc/net/ntohs.c
+++ b/libc/upstream-openbsd/lib/libc/net/ntohs.c
@@ -1,6 +1,5 @@
-/*	$OpenBSD: ntohs.c,v 1.9 2014/07/21 01:51:10 guenther Exp $ */
+/*	$OpenBSD: ntohs.c,v 1.10 2024/04/15 14:30:48 naddy Exp $ */
 /*
- * Written by J.T. Conklin <jtc@netbsd.org>.
  * Public domain.
  */
 
@@ -9,13 +8,8 @@
 
 #undef ntohs
 
-u_int16_t
-ntohs(u_int16_t x)
+uint16_t
+ntohs(uint16_t x)
 {
-#if BYTE_ORDER == LITTLE_ENDIAN
-	u_char *s = (u_char *) &x;
-	return (u_int16_t)(s[0] << 8 | s[1]);
-#else
-	return x;
-#endif
+	return be16toh(x);
 }
diff --git a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
index d83de88..d615245 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: fvwrite.c,v 1.21 2023/10/06 16:41:02 millert Exp $ */
+/*	$OpenBSD: fvwrite.c,v 1.22 2024/04/28 14:28:02 millert Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -31,6 +31,7 @@
  * SUCH DAMAGE.
  */
 
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -76,11 +77,12 @@
 	}
 	if (fp->_flags & __SNBF) {
 		/*
-		 * Unbuffered: write up to BUFSIZ bytes at a time.
+		 * Unbuffered: write up to INT_MAX bytes at a time, to not
+		 * truncate the value of len if it is greater than 2^31 bytes.
 		 */
 		do {
 			GETIOV(;);
-			w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ));
+			w = (*fp->_write)(fp->_cookie, p, MIN(len, INT_MAX));
 			if (w <= 0)
 				goto err;
 			p += w;
@@ -90,7 +92,8 @@
 		/*
 		 * Fully buffered: fill partially full buffer, if any,
 		 * and then flush.  If there is no partial buffer, write
-		 * one _bf._size byte chunk directly (without copying).
+		 * entire payload directly (without copying) up to a
+		 * multiple of the buffer size.
 		 *
 		 * String output is a special case: write as many bytes
 		 * as fit, but pretend we wrote everything.  This makes
@@ -134,7 +137,15 @@
 				if (__sflush(fp))
 					goto err;
 			} else if (len >= (w = fp->_bf._size)) {
-				/* write directly */
+				/*
+				 * Write directly up to INT_MAX or greatest
+				 * multiple of buffer size (whichever is
+				 * smaller), keeping in the memory buffer the
+				 * remaining part of payload that is smaller
+				 * than buffer size.
+				 */
+				if (w != 0)
+					w = MIN(w * (len / w), INT_MAX);
 				w = (*fp->_write)(fp->_cookie, p, w);
 				if (w <= 0)
 					goto err;
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 23cd7f5..8adc342 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -26,15 +26,15 @@
 // dlopen/dlclose.
 static struct {
   uintptr_t v;
-  char padding[max_page_size() - sizeof(v)];
-} shadow_base_storage alignas(max_page_size());
+  char padding[max_android_page_size() - sizeof(v)];
+} shadow_base_storage alignas(max_android_page_size());
 
 // __cfi_init is called by the loader as soon as the shadow is mapped. This may happen very early
 // during startup, before libdl.so global constructors, and, on i386, even before __libc_sysinfo is
 // initialized. This function should not do any system calls.
 extern "C" uintptr_t* __cfi_init(uintptr_t shadow_base) {
   shadow_base_storage.v = shadow_base;
-  static_assert(sizeof(shadow_base_storage) == max_page_size(), "");
+  static_assert(sizeof(shadow_base_storage) == max_android_page_size(), "");
   return &shadow_base_storage.v;
 }
 
diff --git a/linker/arch/arm64/tlsdesc_resolver.S b/linker/arch/arm64/tlsdesc_resolver.S
index ad155e2..84407dd 100644
--- a/linker/arch/arm64/tlsdesc_resolver.S
+++ b/linker/arch/arm64/tlsdesc_resolver.S
@@ -56,12 +56,12 @@
   ldr x22, [x0]                 // TlsDynamicResolverArg::generation
 
   cmp x21, x22
-  b.lo .fallback
+  b.lo L(fallback)
 
   ldr x21, [x0, #8]             // TlsIndex::module_id
   ldr x22, [x0, #16]            // TlsIndex::offset
   ldr x21, [x20, x21, lsl #3]   // TlsDtv::modules[module_id]
-  cbz x21, .fallback
+  cbz x21, L(fallback)
   add x0, x21, x22
   sub x0, x0, x19
 
@@ -75,7 +75,7 @@
   .cfi_restore x20
   ret
 
-.fallback:
+L(fallback):
   .cfi_restore_state
   ldp x21, x22, [sp, #16]
   .cfi_restore x21
diff --git a/linker/linker.cpp b/linker/linker.cpp
index f813c1a..8b467a3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -2788,7 +2788,7 @@
   return true;
 }
 
-void soinfo::apply_relr_reloc(ElfW(Addr) offset) {
+static void apply_relr_reloc(ElfW(Addr) offset, ElfW(Addr) load_bias) {
   ElfW(Addr) address = offset + load_bias;
   *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
 }
@@ -2796,20 +2796,18 @@
 // Process relocations in SHT_RELR section (experimental).
 // Details of the encoding are described in this post:
 //   https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
-bool soinfo::relocate_relr() {
-  ElfW(Relr)* begin = relr_;
-  ElfW(Relr)* end = relr_ + relr_count_;
+bool relocate_relr(const ElfW(Relr)* begin, const ElfW(Relr)* end, ElfW(Addr) load_bias) {
   constexpr size_t wordsize = sizeof(ElfW(Addr));
 
   ElfW(Addr) base = 0;
-  for (ElfW(Relr)* current = begin; current < end; ++current) {
+  for (const ElfW(Relr)* current = begin; current < end; ++current) {
     ElfW(Relr) entry = *current;
     ElfW(Addr) offset;
 
     if ((entry&1) == 0) {
       // Even entry: encodes the offset for next relocation.
       offset = static_cast<ElfW(Addr)>(entry);
-      apply_relr_reloc(offset);
+      apply_relr_reloc(offset, load_bias);
       // Set base offset for subsequent bitmap entries.
       base = offset + wordsize;
       continue;
@@ -2820,7 +2818,7 @@
     while (entry != 0) {
       entry >>= 1;
       if ((entry&1) != 0) {
-        apply_relr_reloc(offset);
+        apply_relr_reloc(offset, load_bias);
       }
       offset += wordsize;
     }
diff --git a/linker/linker.h b/linker/linker.h
index 275182f..ac2222d 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -179,6 +179,7 @@
 int get_application_target_sdk_version();
 ElfW(Versym) find_verdef_version_index(const soinfo* si, const version_info* vi);
 bool validate_verdef_section(const soinfo* si);
+bool relocate_relr(const ElfW(Relr)* begin, const ElfW(Relr)* end, ElfW(Addr) load_bias);
 
 struct platform_properties {
 #if defined(__aarch64__)
diff --git a/linker/linker_crt_pad_segment_test.cpp b/linker/linker_crt_pad_segment_test.cpp
index 5a219f8..c11df50 100644
--- a/linker/linker_crt_pad_segment_test.cpp
+++ b/linker/linker_crt_pad_segment_test.cpp
@@ -72,13 +72,22 @@
 };  // anonymous namespace
 
 TEST(crt_pad_segment, note_absent) {
+  if (!page_size_migration_supported()) {
+    GTEST_SKIP() << "Kernel does not support page size migration";
+  }
   ASSERT_FALSE(GetPadSegment("no_crt_pad_segment.so"));
 }
 
 TEST(crt_pad_segment, note_present_and_enabled) {
+  if (!page_size_migration_supported()) {
+    GTEST_SKIP() << "Kernel does not support page size migration";
+  }
   ASSERT_TRUE(GetPadSegment("crt_pad_segment_enabled.so"));
 }
 
 TEST(crt_pad_segment, note_present_and_disabled) {
+  if (!page_size_migration_supported()) {
+    GTEST_SKIP() << "Kernel does not support page size migration";
+  }
   ASSERT_FALSE(GetPadSegment("crt_pad_segment_disabled.so"));
 }
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index b1fa979..e27fd91 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -29,6 +29,7 @@
 #include "linker_main.h"
 
 #include <link.h>
+#include <stdlib.h>
 #include <sys/auxv.h>
 
 #include "linker.h"
@@ -220,14 +221,10 @@
     exe_path = arg_path;
   }
 
-  // Path might be a symlink
+  // Path might be a symlink; we need the target so that we get the right
+  // linker configuration later.
   char sym_path[PATH_MAX];
-  ssize_t sym_path_len = readlink(exe_path, sym_path, sizeof(sym_path));
-  if (sym_path_len > 0 && sym_path_len < static_cast<ssize_t>(sizeof(sym_path))) {
-    result.path = std::string(sym_path, sym_path_len);
-  } else {
-    result.path = std::string(exe_path, strlen(exe_path));
-  }
+  result.path = std::string(realpath(exe_path, sym_path) != nullptr ? sym_path : exe_path);
 
   result.phdr = reinterpret_cast<const ElfW(Phdr)*>(getauxval(AT_PHDR));
   result.phdr_count = getauxval(AT_PHNUM);
@@ -425,20 +422,11 @@
 
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base);
 
-  // We haven't supported non-PIE since Lollipop for security reasons.
+  // For security reasons we dropped non-PIE support in API level 21,
+  // and the NDK no longer supports earlier API levels.
   if (elf_hdr->e_type != ET_DYN) {
-    // We don't use async_safe_fatal here because we don't want a tombstone:
-    // even after several years we still find ourselves on app compatibility
-    // investigations because some app's trying to launch an executable that
-    // hasn't worked in at least three years, and we've "helpfully" dropped a
-    // tombstone for them. The tombstone never provided any detail relevant to
-    // fixing the problem anyway, and the utility of drawing extra attention
-    // to the problem is non-existent at this late date.
-    async_safe_format_fd(STDERR_FILENO,
-                         "\"%s\": error: Android 5.0 and later only support "
-                         "position-independent executables (-fPIE).\n",
-                         g_argv[0]);
-    _exit(EXIT_FAILURE);
+    __linker_error("error: %s: Android only supports position-independent "
+                   "executables (-fPIE)\n", exe_info.path.c_str());
   }
 
   // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
@@ -635,9 +623,10 @@
   }
 }
 
-static void call_ifunc_resolvers() {
-  // Find the IRELATIVE relocations using the DT_JMPREL and DT_PLTRELSZ, or
-  // DT_RELA/DT_RELASZ (DT_REL/DT_RELSZ on ILP32).
+static void relocate_linker() {
+  // The linker should only have relative relocations (in RELR) and IRELATIVE
+  // relocations. Find the IRELATIVE relocations using the DT_JMPREL and
+  // DT_PLTRELSZ, or DT_RELA/DT_RELASZ (DT_REL/DT_RELSZ on ILP32).
   auto ehdr = reinterpret_cast<ElfW(Addr)>(&__ehdr_start);
   auto* phdr = reinterpret_cast<ElfW(Phdr)*>(ehdr + __ehdr_start.e_phoff);
   for (size_t i = 0; i != __ehdr_start.e_phnum; ++i) {
@@ -645,21 +634,33 @@
       continue;
     }
     auto *dyn = reinterpret_cast<ElfW(Dyn)*>(ehdr + phdr[i].p_vaddr);
-    ElfW(Addr) pltrel = 0, pltrelsz = 0, rel = 0, relsz = 0;
+    ElfW(Addr) relr = 0, relrsz = 0, pltrel = 0, pltrelsz = 0, rel = 0, relsz = 0;
     for (size_t j = 0, size = phdr[i].p_filesz / sizeof(ElfW(Dyn)); j != size; ++j) {
+      const auto tag = dyn[j].d_tag;
+      const auto val = dyn[j].d_un.d_ptr;
       // We don't currently handle IRELATIVE relocations in DT_ANDROID_REL[A].
       // We disabled DT_ANDROID_REL[A] at build time; verify that it was actually disabled.
-      CHECK(dyn[j].d_tag != DT_ANDROID_REL && dyn[j].d_tag != DT_ANDROID_RELA);
-      if (dyn[j].d_tag == DT_JMPREL) {
-        pltrel = dyn[j].d_un.d_ptr;
-      } else if (dyn[j].d_tag == DT_PLTRELSZ) {
-        pltrelsz = dyn[j].d_un.d_ptr;
-      } else if (dyn[j].d_tag == kRelTag) {
-        rel = dyn[j].d_un.d_ptr;
-      } else if (dyn[j].d_tag == kRelSzTag) {
-        relsz = dyn[j].d_un.d_ptr;
+      CHECK(tag != DT_ANDROID_REL && tag != DT_ANDROID_RELA);
+      if (tag == DT_RELR || tag == DT_ANDROID_RELR) {
+        relr = val;
+      } else if (tag == DT_RELRSZ || tag == DT_ANDROID_RELRSZ) {
+        relrsz = val;
+      } else if (tag == DT_JMPREL) {
+        pltrel = val;
+      } else if (tag == DT_PLTRELSZ) {
+        pltrelsz = val;
+      } else if (tag == kRelTag) {
+        rel = val;
+      } else if (tag == kRelSzTag) {
+        relsz = val;
       }
     }
+    // Apply RELR relocations first so that the GOT is initialized for ifunc
+    // resolvers.
+    if (relr && relrsz) {
+      relocate_relr(reinterpret_cast<ElfW(Relr*)>(ehdr + relr),
+                    reinterpret_cast<ElfW(Relr*)>(ehdr + relr + relrsz), ehdr);
+    }
     if (pltrel && pltrelsz) {
       call_ifunc_resolvers_for_section(reinterpret_cast<RelType*>(ehdr + pltrel),
                                        reinterpret_cast<RelType*>(ehdr + pltrel + pltrelsz));
@@ -737,8 +738,12 @@
   ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_addr);
   ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_addr + elf_hdr->e_phoff);
 
-  // string.h functions must not be used prior to calling the linker's ifunc resolvers.
-  call_ifunc_resolvers();
+  // Relocate the linker. This step will initialize the GOT, which is needed for
+  // accessing non-hidden global variables. (On some targets, the stack
+  // protector uses GOT accesses rather than TLS.) Relocating the linker will
+  // also call the linker's ifunc resolvers so that string.h functions can be
+  // used.
+  relocate_linker();
 
   soinfo tmp_linker_so(nullptr, nullptr, nullptr, 0, 0);
 
@@ -750,7 +755,6 @@
   tmp_linker_so.phnum = elf_hdr->e_phnum;
   tmp_linker_so.set_linker_flag();
 
-  // Prelink the linker so we can access linker globals.
   if (!tmp_linker_so.prelink_image()) __linker_cannot_link(args.argv[0]);
   if (!tmp_linker_so.link_image(SymbolLookupList(&tmp_linker_so), &tmp_linker_so, nullptr, nullptr)) __linker_cannot_link(args.argv[0]);
 
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 074012d..b9229ca 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -46,6 +46,8 @@
 #include "private/CFIShadow.h" // For kLibraryAlignment
 #include "private/elf_note.h"
 
+#include <android-base/file.h>
+
 static int GetTargetElfMachine() {
 #if defined(__arm__)
   return EM_ARM;
@@ -296,7 +298,6 @@
   }
 
   if (header_.e_shentsize != sizeof(ElfW(Shdr))) {
-    // Fail if app is targeting Android O or above
     if (get_application_target_sdk_version() >= 26) {
       DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)",
                      name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr)));
@@ -310,12 +311,10 @@
   }
 
   if (header_.e_shstrndx == 0) {
-    // Fail if app is targeting Android O or above
     if (get_application_target_sdk_version() >= 26) {
       DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str());
       return false;
     }
-
     DL_WARN_documented_change(26,
                               "invalid-elf-header_section-headers-enforced-for-api-level-26",
                               "\"%s\" has invalid e_shstrndx", name_.c_str());
@@ -707,8 +706,28 @@
   return true;
 }
 
+/*
+ * Returns true if the kernel supports page size migration, else false.
+ */
+bool page_size_migration_supported() {
+  static bool pgsize_migration_enabled = []() {
+    std::string enabled;
+    if (!android::base::ReadFileToString("/sys/kernel/mm/pgsize_migration/enabled", &enabled)) {
+      return false;
+    }
+    return enabled.find("1") != std::string::npos;
+  }();
+  return pgsize_migration_enabled;
+}
+
 // Find the ELF note of type NT_ANDROID_TYPE_PAD_SEGMENT and check that the desc value is 1.
 bool ElfReader::ReadPadSegmentNote() {
+  if (!page_size_migration_supported()) {
+    // Don't attempt to read the note, since segment extension isn't
+    // supported; but return true so that loading can continue normally.
+    return true;
+  }
+
   // The ELF can have multiple PT_NOTE's, check them all
   for (size_t i = 0; i < phdr_num_; ++i) {
     const ElfW(Phdr)* phdr = &phdr_table_[i];
@@ -724,6 +743,16 @@
       continue;
     }
 
+    // If the PT_NOTE extends beyond the file. The ELF is doing something
+    // strange -- obfuscation, embedding hidden loaders, ...
+    //
+    // It doesn't contain the pad_segment note. Skip it to avoid SIGBUS
+    // by accesses beyond the file.
+    off64_t note_end_off = file_offset_ + phdr->p_offset + phdr->p_filesz;
+    if (note_end_off > file_size_) {
+      continue;
+    }
+
     // note_fragment is scoped to within the loop so that there is
     // at most 1 PT_NOTE mapped at anytime during this search.
     MappedFileFragment note_fragment;
@@ -763,7 +792,16 @@
   const ElfW(Phdr)* next = nullptr;
   size_t next_idx = phdr_idx + 1;
 
-  if (phdr->p_align == kPageSize || !should_pad_segments) {
+  // Don't do segment extension for p_align > 64KiB, such ELFs already existed in the
+  // field e.g. 2MiB p_align for THPs and are relatively small in number.
+  //
+  // The kernel can only represent padding for p_align up to 64KiB. This is because
+  // the kernel uses 4 available bits in the vm_area_struct to represent padding
+  // extent; and so cannot enable mitigations to avoid breaking app compatibility for
+  // p_aligns > 64KiB.
+  //
+  // Don't perform segment extension on these to avoid app compatibility issues.
+  if (phdr->p_align <= kPageSize || phdr->p_align > 64*1024 || !should_pad_segments) {
     return;
   }
 
@@ -877,10 +915,28 @@
     //   2) Break the COW backing, faulting in new anon pages for a region
     //      that will not be used.
 
-    // _seg_file_end = unextended seg_file_end
-    uint64_t _seg_file_end = seg_start + phdr->p_filesz;
-    if ((phdr->p_flags & PF_W) != 0 && page_offset(_seg_file_end) > 0) {
-      memset(reinterpret_cast<void*>(_seg_file_end), 0, kPageSize - page_offset(_seg_file_end));
+    uint64_t unextended_seg_file_end = seg_start + phdr->p_filesz;
+    if ((phdr->p_flags & PF_W) != 0 && page_offset(unextended_seg_file_end) > 0) {
+      memset(reinterpret_cast<void*>(unextended_seg_file_end), 0,
+             kPageSize - page_offset(unextended_seg_file_end));
+    }
+
+    // Pages may be brought in due to readahead.
+    // Drop the padding (zero) pages, to avoid reclaim work later.
+    //
+    // NOTE: The madvise() here is special, as it also serves to hint to the
+    // kernel the portion of the LOAD segment that is padding.
+    //
+    // See: [1] https://android-review.googlesource.com/c/kernel/common/+/3032411
+    //      [2] https://android-review.googlesource.com/c/kernel/common/+/3048835
+    uint64_t pad_start = page_end(unextended_seg_file_end);
+    uint64_t pad_end = page_end(seg_file_end);
+    CHECK(pad_start <= pad_end);
+    uint64_t pad_len = pad_end - pad_start;
+    if (page_size_migration_supported() && pad_len > 0 &&
+        madvise(reinterpret_cast<void*>(pad_start), pad_len, MADV_DONTNEED)) {
+      DL_WARN("\"%s\": madvise(0x%" PRIx64 ", 0x%" PRIx64 ", MADV_DONTNEED) failed: %m",
+              name_.c_str(), pad_start, pad_len);
     }
 
     seg_file_end = page_end(seg_file_end);
@@ -1270,11 +1326,6 @@
 
 
 #if defined(__arm__)
-
-#  ifndef PT_ARM_EXIDX
-#    define PT_ARM_EXIDX    0x70000001      /* .ARM.exidx segment */
-#  endif
-
 /* Return the address and size of the .ARM.exidx section in memory,
  * if present.
  *
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 4deed33..aab9018 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -43,8 +43,8 @@
  public:
   ElfReader();
 
-  bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size);
-  bool Load(address_space_params* address_space);
+  [[nodiscard]] bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size);
+  [[nodiscard]] bool Load(address_space_params* address_space);
 
   const char* name() const { return name_.c_str(); }
   size_t phdr_count() const { return phdr_num_; }
@@ -61,18 +61,18 @@
   bool should_pad_segments() const { return should_pad_segments_; }
 
  private:
-  bool ReadElfHeader();
-  bool VerifyElfHeader();
-  bool ReadProgramHeaders();
-  bool ReadSectionHeaders();
-  bool ReadDynamicSection();
-  bool ReadPadSegmentNote();
-  bool ReserveAddressSpace(address_space_params* address_space);
-  bool LoadSegments();
-  bool FindPhdr();
-  bool FindGnuPropertySection();
-  bool CheckPhdr(ElfW(Addr));
-  bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment);
+  [[nodiscard]] bool ReadElfHeader();
+  [[nodiscard]] bool VerifyElfHeader();
+  [[nodiscard]] bool ReadProgramHeaders();
+  [[nodiscard]] bool ReadSectionHeaders();
+  [[nodiscard]] bool ReadDynamicSection();
+  [[nodiscard]] bool ReadPadSegmentNote();
+  [[nodiscard]] bool ReserveAddressSpace(address_space_params* address_space);
+  [[nodiscard]] bool LoadSegments();
+  [[nodiscard]] bool FindPhdr();
+  [[nodiscard]] bool FindGnuPropertySection();
+  [[nodiscard]] bool CheckPhdr(ElfW(Addr));
+  [[nodiscard]] bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment);
 
   bool did_read_;
   bool did_load_;
@@ -154,3 +154,5 @@
 
 const char* phdr_table_get_interpreter_name(const ElfW(Phdr)* phdr_table, size_t phdr_count,
                                             ElfW(Addr) load_bias);
+
+bool page_size_migration_supported();
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 40299e9..85f7b3a 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -609,9 +609,13 @@
   relocator.tlsdesc_args = &tlsdesc_args_;
   relocator.tls_tp_base = __libc_shared_globals()->static_tls_layout.offset_thread_pointer();
 
-  if (relr_ != nullptr) {
+  // The linker already applied its RELR relocations in an earlier pass, so
+  // skip the RELR relocations for the linker.
+  if (relr_ != nullptr && !is_linker()) {
     DEBUG("[ relocating %s relr ]", get_realpath());
-    if (!relocate_relr()) {
+    const ElfW(Relr)* begin = relr_;
+    const ElfW(Relr)* end = relr_ + relr_count_;
+    if (!relocate_relr(begin, end, load_bias)) {
       return false;
     }
   }
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index a5d31d5..9a13af2 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -384,8 +384,6 @@
 
  private:
   bool relocate(const SymbolLookupList& lookup_list);
-  bool relocate_relr();
-  void apply_relr_reloc(ElfW(Addr) offset);
 
   // This part of the structure is only available
   // when FLAG_NEW_SOINFO is set in this->flags.
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 544af43..f4ef4ac 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -164,9 +164,7 @@
     const char large_string[] = "Hello!!!";
     static_assert(sizeof(large_string) > sizeof(small_buffer), "");
 
-#if __clang_major__ > 13
-    // expected-error@+3{{will always overflow}}
-#endif
+    // expected-error@+2{{will always overflow}}
     // expected-error@+1{{string bigger than buffer}}
     EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
     // expected-error@+1{{string bigger than buffer}}
@@ -204,9 +202,7 @@
     static_assert(sizeof(small_string) > sizeof(split.tiny_buffer), "");
 
 #if _FORTIFY_SOURCE > 1
-#if __clang_major__ > 13
-    // expected-error@+4{{will always overflow}}
-#endif
+    // expected-error@+3{{will always overflow}}
     // expected-error@+2{{string bigger than buffer}}
 #endif
     EXPECT_FORTIFY_DEATH_STRUCT(strcpy(split.tiny_buffer, small_string));
diff --git a/tests/headers/posix/limits_h.c b/tests/headers/posix/limits_h.c
index 7e92d81..0ca80a5 100644
--- a/tests/headers/posix/limits_h.c
+++ b/tests/headers/posix/limits_h.c
@@ -130,10 +130,10 @@
   MACRO(CHARCLASS_NAME_MAX);
   MACRO(COLL_WEIGHTS_MAX);
   MACRO(EXPR_NEST_MAX);
-  MACRO(LINE_MAX);
   MACRO(NGROUPS_MAX);
   MACRO(RE_DUP_MAX);
 #endif
+  MACRO(LINE_MAX);
 
   MACRO_VALUE(_POSIX_CLOCKRES_MIN, 20000000);
 
diff --git a/tests/limits_test.cpp b/tests/limits_test.cpp
index e5902ad..bc13a3f 100644
--- a/tests/limits_test.cpp
+++ b/tests/limits_test.cpp
@@ -21,6 +21,7 @@
 TEST(limits, macros) {
   ASSERT_EQ(8, CHAR_BIT);
   ASSERT_EQ(8 * static_cast<int>(sizeof(int)), WORD_BIT);
+  ASSERT_EQ(2048, LINE_MAX);
   ASSERT_EQ(20, NZERO);
 #if !defined(MB_LEN_MAX)
 #error MB_LEN_MAX
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 2b48d85..a5916d3 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -678,10 +678,12 @@
 TEST(malloc, mallopt_decay) {
 #if defined(__BIONIC__)
   SKIP_WITH_HWASAN << "hwasan does not implement mallopt";
+  ASSERT_EQ(1, mallopt(M_DECAY_TIME, -1));
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 1));
   ASSERT_EQ(1, mallopt(M_DECAY_TIME, 0));
+  ASSERT_EQ(1, mallopt(M_DECAY_TIME, -1));
 #else
   GTEST_SKIP() << "bionic-only test";
 #endif
@@ -1410,15 +1412,15 @@
 }
 
 #if defined(__BIONIC__)
-using Action = android_mallopt_gwp_asan_options_t::Action;
+using Mode = android_mallopt_gwp_asan_options_t::Mode;
 TEST(android_mallopt, DISABLED_multiple_enable_gwp_asan) {
   android_mallopt_gwp_asan_options_t options;
   options.program_name = "";  // Don't infer GWP-ASan options from sysprops.
-  options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN;
+  options.mode = Mode::APP_MANIFEST_NEVER;
   // GWP-ASan should already be enabled. Trying to enable or disable it should
   // always pass.
   ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
-  options.desire = Action::TURN_ON_WITH_SAMPLING;
+  options.mode = Mode::APP_MANIFEST_DEFAULT;
   ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options)));
 }
 #endif  // defined(__BIONIC__)
@@ -1490,7 +1492,7 @@
   // release secondary allocations back to the OS) was modified to 0ms/1ms by
   // mallopt_decay. Ensure that we delay for at least a second before releasing
   // pages to the OS in order to avoid implicit zeroing by the kernel.
-  mallopt(M_DECAY_TIME, 1000);
+  mallopt(M_DECAY_TIME, 1);
   TestHeapZeroing(/* num_iterations */ 32, [](int iteration) -> int {
     return 1 << (19 + iteration % 4);
   });
@@ -1764,6 +1766,10 @@
   EXPECT_EQ(1, mallopt(M_DECAY_TIME, 1));
   EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
   EXPECT_TRUE(value);
+
+  EXPECT_EQ(1, mallopt(M_DECAY_TIME, -1));
+  EXPECT_TRUE(android_mallopt(M_GET_DECAY_TIME_ENABLED, &value, sizeof(value)));
+  EXPECT_FALSE(value);
 #else
   GTEST_SKIP() << "bionic-only test";
 #endif
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 6ae8bfd..0de0a01 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -174,31 +174,23 @@
   }
 }
 
-#if defined(__aarch64__)
+#if defined(__arm__)
+#define SET_FREG(n, v) asm volatile("vmov.f64 d"#n ", #"#v : : : "d"#n)
+#define GET_FREG(n) ({ double _r; asm volatile("fcpyd %P0, d"#n : "=w"(_r) : :); _r;})
+#define CLEAR_FREG(n) asm volatile("vmov.i64 d"#n ", #0x0" : : : "d"#n)
+#elif defined(__aarch64__)
 #define SET_FREG(n, v) asm volatile("fmov d"#n ", "#v : : : "d"#n)
+#define GET_FREG(n) ({ double _r; asm volatile("fmov %0, d"#n : "=r"(_r) : :); _r; })
 #define CLEAR_FREG(n) asm volatile("fmov d"#n ", xzr" : : : "d"#n)
+#endif
+
+#if defined(__arm__) || defined(__aarch64__)
 #define SET_FREGS \
   SET_FREG(8, 8.0); SET_FREG(9, 9.0); SET_FREG(10, 10.0); SET_FREG(11, 11.0); \
   SET_FREG(12, 12.0); SET_FREG(13, 13.0); SET_FREG(14, 14.0); SET_FREG(15, 15.0);
 #define CLEAR_FREGS \
   CLEAR_FREG(8); CLEAR_FREG(9); CLEAR_FREG(10); CLEAR_FREG(11); \
   CLEAR_FREG(12); CLEAR_FREG(13); CLEAR_FREG(14); CLEAR_FREG(15);
-#define GET_FREG(n) ({ double _r; asm volatile("fmov %0, d"#n : "=r"(_r) : :); _r; })
-#define CHECK_FREGS \
-    EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \
-    EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \
-    EXPECT_EQ(12.0, GET_FREG(12)); EXPECT_EQ(13.0, GET_FREG(13)); \
-    EXPECT_EQ(14.0, GET_FREG(14)); EXPECT_EQ(15.0, GET_FREG(15));
-#elif defined(__arm__)
-#define SET_FREG(n, v) \
-  ({ const double _v{v}; asm volatile("fcpyd d"#n ", %P0" : : "w"(_v) : "d"#n); })
-#define SET_FREGS \
-  SET_FREG(8, 8); SET_FREG(9, 9); SET_FREG(10, 10); SET_FREG(11, 11); \
-  SET_FREG(12, 12); SET_FREG(13, 13); SET_FREG(14, 14); SET_FREG(15, 15);
-#define CLEAR_FREGS \
-  SET_FREG(8, 0); SET_FREG(9, 0); SET_FREG(10, 0); SET_FREG(11, 0); \
-  SET_FREG(12, 0); SET_FREG(13, 0); SET_FREG(14, 0); SET_FREG(15, 0);
-#define GET_FREG(n) ({ double _r; asm volatile("fcpyd %P0, d"#n : "=w"(_r) : :); _r;})
 #define CHECK_FREGS \
     EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \
     EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \
diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp
index c4be78c..aea791c 100644
--- a/tests/stack_protector_test.cpp
+++ b/tests/stack_protector_test.cpp
@@ -136,7 +136,7 @@
   if (stack_mte_enabled()) {
     GTEST_SKIP() << "Stack MTE is enabled, stack protector is not available";
   } else if (hwasan_enabled()) {
-    ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT), "tag-mismatch");
+    GTEST_SKIP() << "HWASan is enabled, stack protector is not testable";
   } else {
     ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT),
                 "stack corruption detected");
diff --git a/tests/sys_hwprobe_test.cpp b/tests/sys_hwprobe_test.cpp
index 6b74e18..fd59e1d 100644
--- a/tests/sys_hwprobe_test.cpp
+++ b/tests/sys_hwprobe_test.cpp
@@ -33,6 +33,68 @@
 #include <sys/syscall.h>
 #endif
 
+
+#if defined(__riscv)
+#include <riscv_vector.h>
+
+__attribute__((noinline))
+uint64_t scalar_cast(uint8_t const* p) {
+  return *(uint64_t const*)p;
+}
+
+__attribute__((noinline))
+uint64_t scalar_memcpy(uint8_t const* p) {
+  uint64_t r;
+  __builtin_memcpy(&r, p, sizeof(r));
+  return r;
+}
+
+__attribute__((noinline))
+uint64_t vector_memcpy(uint8_t* d, uint8_t const* p) {
+  __builtin_memcpy(d, p, 16);
+  return *(uint64_t const*)d;
+}
+
+__attribute__((noinline))
+uint64_t vector_ldst(uint8_t* d, uint8_t const* p) {
+  __riscv_vse8(d, __riscv_vle8_v_u8m1(p, 16), 16);
+  return *(uint64_t const*)d;
+}
+
+__attribute__((noinline))
+uint64_t vector_ldst64(uint8_t* d, uint8_t const* p) {
+  __riscv_vse64((unsigned long *)d, __riscv_vle64_v_u64m1((const unsigned long *)p, 16), 16);
+  return *(uint64_t const*)d;
+}
+
+// For testing scalar and vector unaligned accesses.
+uint64_t tmp[3] = {1,1,1};
+uint64_t dst[3] = {1,1,1};
+#endif
+
+TEST(sys_hwprobe, __riscv_hwprobe_misaligned_scalar) {
+#if defined(__riscv)
+  uint8_t* p = (uint8_t*)tmp + 1;
+  ASSERT_NE(0U, scalar_cast(p));
+  ASSERT_NE(0U, scalar_memcpy(p));
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
+
+TEST(sys_hwprobe, __riscv_hwprobe_misaligned_vector) {
+#if defined(__riscv)
+  uint8_t* p = (uint8_t*)tmp + 1;
+  uint8_t* d = (uint8_t*)dst + 1;
+
+  ASSERT_NE(0U, vector_ldst(d, p));
+  ASSERT_NE(0U, vector_memcpy(d, p));
+  ASSERT_NE(0U, vector_ldst64(d, p));
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
+
 TEST(sys_hwprobe, __riscv_hwprobe) {
 #if defined(__riscv) && __has_include(<sys/hwprobe.h>)
   riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0},
@@ -82,4 +144,4 @@
 #else
   GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
 #endif
-}
+}
\ No newline at end of file
diff --git a/tests/sys_statvfs_test.cpp b/tests/sys_statvfs_test.cpp
index 73b2a96..5dd7b93 100644
--- a/tests/sys_statvfs_test.cpp
+++ b/tests/sys_statvfs_test.cpp
@@ -25,7 +25,7 @@
 #include <string>
 
 template <typename StatVfsT> void Check(StatVfsT& sb) {
-  EXPECT_EQ(4096U, sb.f_bsize);
+  EXPECT_EQ(getpagesize(), static_cast<int>(sb.f_bsize));
   EXPECT_EQ(0U, sb.f_bfree);
   EXPECT_EQ(0U, sb.f_ffree);
   EXPECT_EQ(255U, sb.f_namemax);
diff --git a/tests/sys_vfs_test.cpp b/tests/sys_vfs_test.cpp
index 96fd61a..e783190 100644
--- a/tests/sys_vfs_test.cpp
+++ b/tests/sys_vfs_test.cpp
@@ -27,7 +27,7 @@
 #include "utils.h"
 
 template <typename StatFsT> void Check(StatFsT& sb) {
-  EXPECT_EQ(4096, static_cast<int>(sb.f_bsize));
+  EXPECT_EQ(getpagesize(), static_cast<int>(sb.f_bsize));
   EXPECT_EQ(0U, sb.f_bfree);
   EXPECT_EQ(0U, sb.f_ffree);
   EXPECT_EQ(255, static_cast<int>(sb.f_namelen));
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index ca8e260..baafbf6 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -31,6 +31,8 @@
 #include <thread>
 
 #include "SignalUtils.h"
+#include "android-base/file.h"
+#include "android-base/strings.h"
 #include "utils.h"
 
 using namespace std::chrono_literals;
@@ -797,21 +799,41 @@
   ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
 }
 
-TEST(time, timer_create_EINVAL) {
-  clockid_t invalid_clock = 16;
+static int GetThreadCount() {
+  std::string status;
+  if (android::base::ReadFileToString("/proc/self/status", &status)) {
+    for (const auto& line : android::base::Split(status, "\n")) {
+      int thread_count;
+      if (sscanf(line.c_str(), "Threads: %d", &thread_count) == 1) {
+        return thread_count;
+      }
+    }
+  }
+  return -1;
+}
 
-  // A SIGEV_SIGNAL timer is easy; the kernel does all that.
+TEST(time, timer_create_EINVAL) {
+  const clockid_t kInvalidClock = 16;
+
+  // A SIGEV_SIGNAL timer failure is easy; that's the kernel's problem.
   timer_t timer_id;
-  ASSERT_EQ(-1, timer_create(invalid_clock, nullptr, &timer_id));
+  ASSERT_EQ(-1, timer_create(kInvalidClock, nullptr, &timer_id));
   ASSERT_ERRNO(EINVAL);
 
-  // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
-  sigevent se;
-  memset(&se, 0, sizeof(se));
+  // A SIGEV_THREAD timer failure is more interesting because we have a thread
+  // to clean up (https://issuetracker.google.com/340125671).
+  sigevent se = {};
   se.sigev_notify = SIGEV_THREAD;
   se.sigev_notify_function = NoOpNotifyFunction;
-  ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
+  ASSERT_EQ(-1, timer_create(kInvalidClock, &se, &timer_id));
   ASSERT_ERRNO(EINVAL);
+
+  // timer_create() doesn't guarantee that the thread will be dead _before_
+  // it returns because that would require extra synchronization that's
+  // unnecessary in the normal (successful) case. A timeout here means we
+  // leaked a thread.
+  while (GetThreadCount() > 1) {
+  }
 }
 
 TEST(time, timer_create_multiple) {
diff --git a/tests/utils.h b/tests/utils.h
index dcb08f5..3c83b73 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -38,6 +38,7 @@
 #endif
 
 #include <atomic>
+#include <iomanip>
 #include <string>
 #include <regex>
 
@@ -253,7 +254,7 @@
     AssertChildExited(pid, expected_exit_status, &error_msg);
     if (expected_output_regex != nullptr) {
       if (!std::regex_search(output_, std::regex(expected_output_regex))) {
-        FAIL() << "regex " << expected_output_regex << " didn't match " << output_;
+        FAIL() << "regex " << std::quoted(expected_output_regex) << " didn't match " << std::quoted(output_);
       }
     }
   }