Merge "Don't assume size of functions." into main
diff --git a/README.md b/README.md
index 113ffd7..aafbcff 100644
--- a/README.md
+++ b/README.md
@@ -374,6 +374,19 @@
 
     $ ./tests/run-on-host.sh glibc
 
+### Against musl
+
+Another way to verify test behavior is to run against musl on the host. glibc
+musl don't always match, so this can be a good way to find the more complicated
+corners of the spec. If they *do* match, bionic probably should too!
+
+    $ OUT_DIR=$(ANDROID_BUILD_TOP)/musl-out ./tests/run-on-host.sh musl
+
+Note: the alternate OUT_DIR is used to avoid causing excessive rebuilding when
+switching between glibc and musl. The first musl test run will be expensive
+because it will not reuse any already built artifacts, but subsequent runs will
+be cheaper than if you hadn't used it.
+
 ## Gathering test coverage
 
 To get test coverage for bionic, use `//bionic/build/coverage.sh`. Before
diff --git a/docs/status.md b/docs/status.md
index 1838b85..5514935 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -62,6 +62,8 @@
     functions for avoiding $TZ if you need to use multiple timezones in
     multi-threaded C).
   * `mbsrtowcs_l` and `wcsrtombs_l` aliases for `mbsrtowcs` and `wcsrtombs`.
+  * New system call wrappers: `__riscv_flush_icache` (`<sys/cachectl.h>`),
+    `__riscv_hwprobe` (`<sys/hwprobe.h>`).
 
 New libc functions in U (API level 34):
   * `close_range` and `copy_file_range` (Linux-specific GNU extensions).
diff --git a/libc/Android.bp b/libc/Android.bp
index dc3c73f..aa555a1 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -133,6 +133,8 @@
     lto: {
         never: true,
     },
+
+    apex_available: ["com.android.runtime"],
 }
 
 libc_scudo_product_variables = {
@@ -334,10 +336,16 @@
 // automatically included.
 
 cc_library_static {
+    name: "libc_freebsd_ldexp",
+    defaults: ["libc_defaults"],
+    cflags: ["-Dscalbn=ldexp"],
+    srcs: [":libc_ldexp_srcs"],
+}
+
+cc_library_static {
     defaults: ["libc_defaults"],
     tidy_disabled_srcs: ["upstream-*/**/*.c"],
     srcs: [
-        "upstream-freebsd/lib/libc/gen/ldexp.c",
         "upstream-freebsd/lib/libc/stdlib/getopt_long.c",
         "upstream-freebsd/lib/libc/stdlib/hcreate.c",
         "upstream-freebsd/lib/libc/stdlib/hcreate_r.c",
@@ -1276,9 +1284,6 @@
     srcs: [
         "bionic/bionic_systrace.cpp",
     ],
-    apex_available: [
-        "com.android.runtime",
-    ],
 }
 
 // ========================================================
@@ -1475,6 +1480,7 @@
         "libc_fortify",
         "libc_freebsd",
         "libc_freebsd_large_stack",
+        "libc_freebsd_ldexp",
         "libc_gdtoa",
         "libc_netbsd",
         "libc_openbsd_large_stack",
@@ -1509,6 +1515,7 @@
         "libc_fortify",
         "libc_freebsd",
         "libc_freebsd_large_stack",
+        "libc_freebsd_ldexp",
         "libc_gdtoa",
         "libc_netbsd",
         "libc_openbsd",
@@ -1831,7 +1838,6 @@
         },
     },
 
-
     apex_available: [
         "//apex_available:platform",
         "com.android.runtime",
@@ -2095,6 +2101,9 @@
     name: "libstdc++",
     static_ndk_lib: true,
     static_libs: ["libasync_safe"],
+    apex_available: [
+        "//apex_available:platform",
+    ],
 
     static: {
         system_shared_libs: [],
diff --git a/libc/SECCOMP_ALLOWLIST_COMMON.TXT b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
index efbf28b..67b662e 100644
--- a/libc/SECCOMP_ALLOWLIST_COMMON.TXT
+++ b/libc/SECCOMP_ALLOWLIST_COMMON.TXT
@@ -53,6 +53,7 @@
 int execveat(int, const char*, char* const*, char* const*, int)  all
 # Since Linux 4.3, not in glibc. Probed for and conditionally used by ART.
 int membarrier(int, int) all
+int userfaultfd(int) all
 # Since Linux 5.1, not in glibc. Not used by bionic, and not likely ever
 # to be (because the last thing anyone needs is a new 32-bit ABI in the
 # 2020s!) but http://b/138781460 showed cuttlefish needed at least the
@@ -73,5 +74,3 @@
 int rt_sigtimedwait_time64(const sigset64_t*, siginfo_t*, const timespec64*, size_t) lp32
 int futex_time64(int*, int, int, const timespec64*, int*, int) lp32
 int sched_rr_get_interval_time64(pid_t, timespec64*) lp32
-# Since Linux 5.4, not in glibc. Probed for and conditionally used by ART.
-int userfaultfd(int) all
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 08017f1..079acf9 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -161,7 +161,7 @@
 int linkat(int, const char*, int, const char*, int)  all
 int mkdirat(int, const char*, mode_t)  all
 int mknodat(int, const char*, mode_t, dev_t)  all
-int readlinkat(int, const char*, char*, size_t)  all
+ssize_t readlinkat(int, const char*, char*, size_t)  all
 int renameat2(int, const char*, int, const char*, unsigned)  all
 int symlinkat(const char*, int, const char*)  all
 int unlinkat(int, const char*, int)   all
@@ -356,7 +356,8 @@
 int     cacheflush:__ARM_NR_cacheflush(long start, long end, long flags)  arm
 
 # riscv64-specific
-int _flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
+int __riscv_flush_icache:riscv_flush_icache(void*, void*, unsigned long) riscv64
+int __riscv_hwprobe:riscv_hwprobe(riscv_hwprobe*, size_t, size_t, unsigned long*, unsigned) riscv64
 
 # x86-specific
 int     __set_thread_area:set_thread_area(void*) x86
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 95f46e9..1b539f2 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -150,7 +150,7 @@
   // stack.)
   ThreadMapping mapping = __allocate_thread_mapping(0, PTHREAD_GUARD_SIZE);
   if (mapping.mmap_base == nullptr) {
-    async_safe_fatal("failed to mmap main thread static TLS: %s", strerror(errno));
+    async_safe_fatal("failed to mmap main thread static TLS: %m");
   }
 
   const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 8c9127e..849d04b 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -126,15 +126,14 @@
 static void HandleTracedPerfSignal() {
   ScopedFd sock_fd{ socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0 /*protocol*/) };
   if (sock_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create socket: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to create socket: %m");
     return;
   }
 
   sockaddr_un saddr{ AF_UNIX, "/dev/socket/traced_perf" };
   size_t addrlen = sizeof(sockaddr_un);
   if (connect(sock_fd.get(), reinterpret_cast<const struct sockaddr*>(&saddr), addrlen) == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to traced_perf socket: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to connect to traced_perf socket: %m");
     return;
   }
 
@@ -153,13 +152,11 @@
   }
 
   if (maps_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %m");
     return;
   }
   if (mem_fd.get() == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %s",
-                          strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %m");
     return;
   }
 
@@ -183,7 +180,7 @@
   memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
 
   if (sendmsg(sock_fd.get(), &msg_hdr, 0) == -1) {
-    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to sendmsg: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to sendmsg: %m");
   }
 }
 
diff --git a/libc/bionic/atexit.cpp b/libc/bionic/atexit.cpp
index dae15e0..29f9c7b 100644
--- a/libc/bionic/atexit.cpp
+++ b/libc/bionic/atexit.cpp
@@ -158,7 +158,7 @@
 
   const int prot = PROT_READ | (writable ? PROT_WRITE : 0);
   if (mprotect(reinterpret_cast<char*>(array_) + start_byte, byte_len, prot) != 0) {
-    async_safe_fatal("mprotect failed on atexit array: %s", strerror(errno));
+    async_safe_fatal("mprotect failed on atexit array: %m");
   }
 }
 
@@ -198,8 +198,8 @@
   }
   if (new_pages == MAP_FAILED) {
     async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                          "__cxa_atexit: mmap/mremap failed to allocate %zu bytes: %s",
-                          new_capacity_bytes, strerror(errno));
+                          "__cxa_atexit: mmap/mremap failed to allocate %zu bytes: %m",
+                          new_capacity_bytes);
   } else {
     result = true;
     prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, new_pages, new_capacity_bytes, "atexit handlers");
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 53f944f..80e8b08 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -192,7 +192,7 @@
   void* const map_ptr =
       mmap(nullptr, page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (map_ptr == MAP_FAILED) {
-    async_safe_fatal("mmap failed: %s", strerror(errno));
+    async_safe_fatal("mmap failed: %m");
   }
 
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, page_size(), "bionic_alloc_small_objects");
@@ -273,7 +273,7 @@
                        -1, 0);
 
   if (map_ptr == MAP_FAILED) {
-    async_safe_fatal("mmap failed: %s", strerror(errno));
+    async_safe_fatal("mmap failed: %m");
   }
 
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "bionic_alloc_lob");
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index 3eb8c19..84d2c94 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -87,7 +87,7 @@
     void* allocation =
         mmap(nullptr, aligned_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
     if (allocation == MAP_FAILED) {
-      async_safe_fatal("fdsan: mmap failed: %s", strerror(errno));
+      async_safe_fatal("fdsan: mmap failed: %m");
     }
 
     FdTableOverflow* new_overflow = reinterpret_cast<FdTableOverflow*>(allocation);
diff --git a/libc/bionic/ifaddrs.cpp b/libc/bionic/ifaddrs.cpp
index 0c80f4e..cb36cc6 100644
--- a/libc/bionic/ifaddrs.cpp
+++ b/libc/bionic/ifaddrs.cpp
@@ -281,8 +281,7 @@
   ScopedFd s(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
   if (s.get() == -1) {
     async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                          "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %s",
-                          strerror(errno));
+                          "socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC) failed in ifaddrs: %m");
     return;
   }
 
@@ -294,8 +293,8 @@
       addr->ifa.ifa_flags = ifr.ifr_flags;
     } else {
       async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                            "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %s",
-                            addr->ifa.ifa_name, strerror(errno));
+                            "ioctl(SIOCGIFFLAGS) for \"%s\" failed in ifaddrs: %m",
+                            addr->ifa.ifa_name);
     }
   }
 }
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index d922641..7ef79b6 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -340,11 +340,11 @@
 #if !defined(__LP64__)
   int old_value = personality(0xffffffff);
   if (old_value == -1) {
-    async_safe_fatal("error getting old personality value: %s", strerror(errno));
+    async_safe_fatal("error getting old personality value: %m");
   }
 
   if (personality((static_cast<unsigned int>(old_value) & ~PER_MASK) | PER_LINUX32) == -1) {
-    async_safe_fatal("error setting PER_LINUX32 personality: %s", strerror(errno));
+    async_safe_fatal("error setting PER_LINUX32 personality: %m");
   }
 #endif
 }
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 3b0ab82..d7a2856 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -357,8 +357,7 @@
         void* pg_start =
             reinterpret_cast<void*>(page_start(reinterpret_cast<uintptr_t>(stack_top)));
         if (mprotect(pg_start, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_MTE | PROT_GROWSDOWN)) {
-          async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %s\n",
-                           strerror(errno));
+          async_safe_fatal("error: failed to set PROT_MTE on main thread stack: %m");
         }
       }
 
diff --git a/libc/bionic/poll.cpp b/libc/bionic/poll.cpp
index 3290315..7d80b4c 100644
--- a/libc/bionic/poll.cpp
+++ b/libc/bionic/poll.cpp
@@ -50,14 +50,8 @@
 
 int ppoll(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset_t* ss) {
   // The underlying `__ppoll` system call only takes `sigset64_t`.
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return ppoll64(fds, fd_count, ts, ss_ptr);
+  SigSetConverter set{ss};
+  return ppoll64(fds, fd_count, ts, set.ptr);
 }
 
 int ppoll64(pollfd* fds, nfds_t fd_count, const timespec* ts, const sigset64_t* ss) {
@@ -99,14 +93,8 @@
 int pselect(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
             const timespec* ts, const sigset_t* ss) {
   // The underlying `__pselect6` system call only takes `sigset64_t`.
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, ss_ptr);
+  SigSetConverter set{ss};
+  return pselect64(fd_count, read_fds, write_fds, error_fds, ts, set.ptr);
 }
 
 int pselect64(int fd_count, fd_set* read_fds, fd_set* write_fds, fd_set* error_fds,
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
index cdae72c..de4cc9e 100644
--- a/libc/bionic/pthread_attr.cpp
+++ b/libc/bionic/pthread_attr.cpp
@@ -158,12 +158,12 @@
 static uintptr_t __get_main_stack_startstack() {
   FILE* fp = fopen("/proc/self/stat", "re");
   if (fp == nullptr) {
-    async_safe_fatal("couldn't open /proc/self/stat: %s", strerror(errno));
+    async_safe_fatal("couldn't open /proc/self/stat: %m");
   }
 
   char line[BUFSIZ];
   if (fgets(line, sizeof(line), fp) == nullptr) {
-    async_safe_fatal("couldn't read /proc/self/stat: %s", strerror(errno));
+    async_safe_fatal("couldn't read /proc/self/stat: %m");
   }
 
   fclose(fp);
@@ -205,7 +205,7 @@
   // Hunt for the region that contains that address.
   FILE* fp = fopen("/proc/self/maps", "re");
   if (fp == nullptr) {
-    async_safe_fatal("couldn't open /proc/self/maps: %s", strerror(errno));
+    async_safe_fatal("couldn't open /proc/self/maps: %m");
   }
   char line[BUFSIZ];
   while (fgets(line, sizeof(line), fp) != nullptr) {
@@ -219,7 +219,7 @@
       }
     }
   }
-  async_safe_fatal("Stack not found in /proc/self/maps");
+  async_safe_fatal("stack not found in /proc/self/maps");
 }
 
 __BIONIC_WEAK_FOR_NATIVE_BRIDGE
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index b46c6cf..194db18 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -78,8 +78,7 @@
                           MAP_PRIVATE | MAP_ANONYMOUS,
                           -1, 0);
   if (allocation == MAP_FAILED) {
-    // Avoid strerror because it might need bionic_tls.
-    async_safe_fatal("failed to allocate bionic_tls: error %d", errno);
+    async_safe_fatal("failed to allocate bionic_tls: %m");
   }
   return static_cast<bionic_tls*>(allocation);
 }
@@ -137,7 +136,9 @@
   // Make the stack read-write, and store its address in the register we're using as the shadow
   // stack pointer. This is deliberately the only place where the address is stored.
   char* scs = scs_aligned_guard_region + scs_offset;
-  mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
+  if (mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE) == -1) {
+    async_safe_fatal("shadow stack read-write mprotect(%p, %d) failed: %m", scs, SCS_SIZE);
+  }
 #if defined(__aarch64__)
   __asm__ __volatile__("mov x18, %0" ::"r"(scs));
 #elif defined(__riscv)
@@ -171,12 +172,11 @@
     if (need_set) {
       if (policy == -1) {
         async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                              "pthread_create sched_getscheduler failed: %s", strerror(errno));
+                              "pthread_create sched_getscheduler failed: %m");
         return errno;
       }
       if (sched_getparam(0, &param) == -1) {
-        async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                              "pthread_create sched_getparam failed: %s", strerror(errno));
+        async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create sched_getparam failed: %m");
         return errno;
       }
     }
@@ -192,8 +192,8 @@
   if (need_set) {
     if (sched_setscheduler(thread->tid, policy, &param) == -1) {
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "pthread_create sched_setscheduler(%d, {%d}) call failed: %s", policy,
-                            param.sched_priority, strerror(errno));
+                            "pthread_create sched_setscheduler(%d, {%d}) call failed: %m", policy,
+                            param.sched_priority);
 #if defined(__LP64__)
       // For backwards compatibility reasons, we only report failures on 64-bit devices.
       return errno;
@@ -228,10 +228,9 @@
   const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
   char* const space = static_cast<char*>(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0));
   if (space == MAP_FAILED) {
-    async_safe_format_log(ANDROID_LOG_WARN,
-                          "libc",
-                          "pthread_create failed: couldn't allocate %zu-bytes mapped space: %s",
-                          mmap_size, strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                          "pthread_create failed: couldn't allocate %zu-bytes mapped space: %m",
+                          mmap_size);
     return {};
   }
   const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
@@ -246,8 +245,8 @@
   if (mprotect(space + stack_guard_size, writable_size, prot) != 0) {
     async_safe_format_log(
         ANDROID_LOG_WARN, "libc",
-        "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %s", prot_str,
-        writable_size, strerror(errno));
+        "pthread_create failed: couldn't mprotect %s %zu-byte thread mapping region: %m", prot_str,
+        writable_size);
     munmap(space, mmap_size);
     return {};
   }
@@ -458,8 +457,7 @@
     if (thread->mmap_size != 0) {
       munmap(thread->mmap_base, thread->mmap_size);
     }
-    async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s",
-                          strerror(clone_errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %m");
     return clone_errno;
   }
 
diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp
index b581b5a..2cf9940 100644
--- a/libc/bionic/signal.cpp
+++ b/libc/bionic/signal.cpp
@@ -76,13 +76,23 @@
   return SigAddSet(set, sig);
 }
 
-// This isn't in our header files, but is exposed on all architectures.
+union BsdSigSet {
+  int mask;
+  sigset64_t set;
+};
+
+// This isn't in our header files, but is exposed on all architectures except riscv64.
 extern "C" int sigblock(int mask) {
-  SigSetConverter in, out;
-  sigemptyset(&in.sigset);
-  in.bsd = mask;
-  if (sigprocmask(SIG_BLOCK, &in.sigset, &out.sigset) == -1) return -1;
-  return out.bsd;
+  BsdSigSet in{.mask = mask}, out;
+  if (sigprocmask64(SIG_BLOCK, &in.set, &out.set) == -1) return -1;
+  return out.mask;
+}
+
+// This isn't in our header files, but is exposed on all architectures except riscv64.
+extern "C" int sigsetmask(int mask) {
+  BsdSigSet in{.mask = mask}, out;
+  if (sigprocmask64(SIG_SETMASK, &in.set, &out.set) == -1) return -1;
+  return out.mask;
 }
 
 template <typename SigSetT>
@@ -198,10 +208,9 @@
 }
 
 int sigpending(sigset_t* bionic_set) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  if (__rt_sigpending(&set.sigset64, sizeof(set.sigset64)) == -1) return -1;
-  *bionic_set = set.sigset;
+  SigSetConverter set{bionic_set};
+  if (__rt_sigpending(set.ptr, sizeof(sigset64_t)) == -1) return -1;
+  set.copy_out();
   return 0;
 }
 
@@ -245,19 +254,9 @@
   return sigismember64(&old_mask, sig) ? SIG_HOLD : old_sa.sa_handler;
 }
 
-// This isn't in our header files, but is exposed on all architectures.
-extern "C" int sigsetmask(int mask) {
-  SigSetConverter in, out;
-  sigemptyset(&in.sigset);
-  in.bsd = mask;
-  if (sigprocmask(SIG_SETMASK, &in.sigset, &out.sigset) == -1) return -1;
-  return out.bsd;
-}
-
 int sigsuspend(const sigset_t* bionic_set) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigsuspend64(&set.sigset64);
+  SigSetConverter set{bionic_set};
+  return sigsuspend64(set.ptr);
 }
 
 int sigsuspend64(const sigset64_t* set) {
@@ -271,9 +270,8 @@
 }
 
 int sigtimedwait(const sigset_t* bionic_set, siginfo_t* info, const timespec* timeout) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigtimedwait64(&set.sigset64, info, timeout);
+  SigSetConverter set{bionic_set};
+  return sigtimedwait64(set.ptr, info, timeout);
 }
 
 int sigtimedwait64(const sigset64_t* set, siginfo_t* info, const timespec* timeout) {
@@ -287,9 +285,8 @@
 }
 
 int sigwait(const sigset_t* bionic_set, int* sig) {
-  SigSetConverter set = {};
-  set.sigset = *bionic_set;
-  return sigwait64(&set.sigset64, sig);
+  SigSetConverter set{bionic_set};
+  return sigwait64(set.ptr, sig);
 }
 
 int sigwait64(const sigset64_t* set, int* sig) {
diff --git a/libc/bionic/sigprocmask.cpp b/libc/bionic/sigprocmask.cpp
index 8781c9b..6d436a6 100644
--- a/libc/bionic/sigprocmask.cpp
+++ b/libc/bionic/sigprocmask.cpp
@@ -44,24 +44,13 @@
 int sigprocmask(int how,
                 const sigset_t* bionic_new_set,
                 sigset_t* bionic_old_set) __attribute__((__noinline__)) {
-  SigSetConverter new_set;
-  sigset64_t* new_set_ptr = nullptr;
-  if (bionic_new_set != nullptr) {
-    sigemptyset64(&new_set.sigset64);
-    new_set.sigset = *bionic_new_set;
-    new_set_ptr = &new_set.sigset64;
+  SigSetConverter new_set{bionic_new_set};
+  SigSetConverter old_set{bionic_old_set};
+  int rc = sigprocmask64(how, new_set.ptr, old_set.ptr);
+  if (rc == 0 && bionic_old_set != nullptr) {
+    old_set.copy_out();
   }
-
-  SigSetConverter old_set;
-  if (sigprocmask64(how, new_set_ptr, &old_set.sigset64) == -1) {
-    return -1;
-  }
-
-  if (bionic_old_set != nullptr) {
-    *bionic_old_set = old_set.sigset;
-  }
-
-  return 0;
+  return rc;
 }
 
 int sigprocmask64(int how,
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 5d76f77..38f99ad 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -41,7 +41,6 @@
 #include <android/fdsan.h>
 
 #include "private/ScopedSignalBlocker.h"
-#include "private/SigSetConverter.h"
 
 static int set_cloexec(int i) {
   int v = fcntl(i, F_GETFD);
@@ -131,8 +130,10 @@
   pid_t pgroup;
   sched_param schedparam;
   int schedpolicy;
-  SigSetConverter sigmask;
-  SigSetConverter sigdefault;
+  union {
+    sigset_t sigset;
+    sigset64_t sigset64;
+  } sigmask, sigdefault;
 };
 
 static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) {
diff --git a/libc/bionic/sys_epoll.cpp b/libc/bionic/sys_epoll.cpp
index 22d0a98..cffa173 100644
--- a/libc/bionic/sys_epoll.cpp
+++ b/libc/bionic/sys_epoll.cpp
@@ -48,14 +48,8 @@
 }
 
 int epoll_pwait(int fd, epoll_event* events, int max_events, int timeout, const sigset_t* ss) {
-  SigSetConverter set;
-  sigset64_t* ss_ptr = nullptr;
-  if (ss != nullptr) {
-    set = {};
-    set.sigset = *ss;
-    ss_ptr = &set.sigset64;
-  }
-  return epoll_pwait64(fd, events, max_events, timeout, ss_ptr);
+  SigSetConverter set{ss};
+  return epoll_pwait64(fd, events, max_events, timeout, set.ptr);
 }
 
 int epoll_pwait64(int fd, epoll_event* events, int max_events, int timeout, const sigset64_t* ss) {
diff --git a/libc/bionic/sys_signalfd.cpp b/libc/bionic/sys_signalfd.cpp
index 53d1f25..1e62cf4 100644
--- a/libc/bionic/sys_signalfd.cpp
+++ b/libc/bionic/sys_signalfd.cpp
@@ -32,12 +32,12 @@
 
 extern "C" int __signalfd4(int, const sigset64_t*, size_t, int);
 
-int signalfd(int fd, const sigset_t* mask, int flags) {
-  SigSetConverter set = {};
-  set.sigset = *mask;
-  return signalfd64(fd, &set.sigset64, flags);
-}
-
 int signalfd64(int fd, const sigset64_t* mask, int flags) {
   return __signalfd4(fd, mask, sizeof(*mask), flags);
 }
+
+int signalfd(int fd, const sigset_t* mask, int flags) {
+  // The underlying `__signalfd4` system call only takes `sigset64_t`.
+  SigSetConverter set{mask};
+  return signalfd64(fd, set.ptr, flags);
+}
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index 212aafc..f7999db 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -272,10 +272,9 @@
     PropertyServiceConnection connection;
     if (!connection.IsValid()) {
       errno = connection.GetLastError();
-      async_safe_format_log(
-          ANDROID_LOG_WARN, "libc",
-          "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", key, value,
-          errno, strerror(errno));
+      async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                            "Unable to set property \"%s\" to \"%s\": connection failed: %m", key,
+                            value);
       return -1;
     }
 
@@ -283,8 +282,8 @@
     if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
       errno = connection.GetLastError();
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
-                            key, value, errno, strerror(errno));
+                            "Unable to set property \"%s\" to \"%s\": write failed: %m", key,
+                            value);
       return -1;
     }
 
@@ -292,8 +291,7 @@
     if (!connection.RecvInt32(&result)) {
       errno = connection.GetLastError();
       async_safe_format_log(ANDROID_LOG_WARN, "libc",
-                            "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
-                            key, value, errno, strerror(errno));
+                            "Unable to set property \"%s\" to \"%s\": recv failed: %m", key, value);
       return -1;
     }
 
diff --git a/libc/include/bits/getentropy.h b/libc/include/bits/getentropy.h
new file mode 100644
index 0000000..a5a14f7
--- /dev/null
+++ b/libc/include/bits/getentropy.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+/**
+ * @file bits/getentropy.h
+ * @brief The getentropy() function.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/**
+ * [getentropy(3)](http://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
+ * with random bytes.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ *
+ * Available since API level 28.
+ *
+ * See also arc4random_buf() which is available in all API levels.
+ */
+int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+
+__END_DECLS
diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h
index 79f7da0..3b4b5bf 100644
--- a/libc/include/bits/glibc-syscalls.h
+++ b/libc/include/bits/glibc-syscalls.h
@@ -909,6 +909,9 @@
 #if defined(__NR_riscv_flush_icache)
   #define SYS_riscv_flush_icache __NR_riscv_flush_icache
 #endif
+#if defined(__NR_riscv_hwprobe)
+  #define SYS_riscv_hwprobe __NR_riscv_hwprobe
+#endif
 #if defined(__NR_rmdir)
   #define SYS_rmdir __NR_rmdir
 #endif
diff --git a/libc/include/sys/cachectl.h b/libc/include/sys/cachectl.h
index 5ec295d..b5fabe3 100644
--- a/libc/include/sys/cachectl.h
+++ b/libc/include/sys/cachectl.h
@@ -28,6 +28,32 @@
 
 #pragma once
 
+/*
+ * @file sys/cachectl.h
+ * @brief Architecture-specific cache control.
+ */
+
 #include <sys/cdefs.h>
 
-/* This header file is obsolete. */
+__BEGIN_DECLS
+
+#if defined(__riscv)
+
+/**
+ * Flag for __riscv_flush_icache() to indicate that only the current
+ * thread's instruction cache needs to be flushed (rather than the
+ * default of all threads).
+ */
+#define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL
+
+/**
+ * __riscv_flush_icache(2) flushes the instruction cache for the given range of addresses.
+ * The address range is currently (Linux 6.4) ignored, so both pointers may be null.
+ *
+ * Returns 0 on success, and returns -1 and sets `errno` on failure.
+ */
+int __riscv_flush_icache(void* _Nullable __start, void* _Nullable __end, unsigned long __flags);
+
+#endif
+
+__END_DECLS
diff --git a/libc/include/sys/hwprobe.h b/libc/include/sys/hwprobe.h
new file mode 100644
index 0000000..f2fd98d
--- /dev/null
+++ b/libc/include/sys/hwprobe.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if __riscv
+
+/**
+ * @file sys/hwprobe.h
+ * @brief RISC-V hardware probing.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/* Pull in struct riscv_hwprobe and corresponding constants. */
+#include <asm/hwprobe.h>
+
+__BEGIN_DECLS
+
+/**
+ * [__riscv_hwprobe(2)](https://docs.kernel.org/riscv/hwprobe.html)
+ * queries hardware characteristics.
+ *
+ * A `__cpu_count` of 0 and null `__cpus` means "all online cpus".
+ *
+ * Returns 0 on success and returns -1 and sets `errno` on failure.
+ */
+int __riscv_hwprobe(struct riscv_hwprobe* _Nonnull __pairs, size_t __pair_count, size_t __cpu_count, unsigned long* _Nullable __cpus, unsigned __flags);
+
+__END_DECLS
+
+#endif
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index 0251176..2ff5349 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -38,19 +38,9 @@
 
 #include <linux/random.h>
 
-__BEGIN_DECLS
+#include <bits/getentropy.h>
 
-/**
- * [getentropy(3)](http://man7.org/linux/man-pages/man3/getentropy.3.html) fills the given buffer
- * with random bytes.
- *
- * Returns 0 on success, and returns -1 and sets `errno` on failure.
- *
- * Available since API level 28.
- *
- * See also arc4random_buf() which is available in all API levels.
- */
-int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+__BEGIN_DECLS
 
 /**
  * [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 9385264..dcad630 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -34,6 +34,7 @@
 #include <sys/select.h>
 
 #include <bits/fcntl.h>
+#include <bits/getentropy.h>
 #include <bits/getopt.h>
 #include <bits/ioctl.h>
 #include <bits/lockf.h>
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index a413b36..ea690eb 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -126,6 +126,10 @@
   __u64 flags;
   __u64 reserved[2];
 };
+struct kvm_arm_counter_offset {
+  __u64 counter_offset;
+  __u64 reserved;
+};
 #define KVM_ARM_TAGS_TO_GUEST 0
 #define KVM_ARM_TAGS_FROM_GUEST 1
 #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000
@@ -204,6 +208,8 @@
   KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0,
   KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1,
 };
+#define KVM_ARM_VM_SMCCC_CTRL 0
+#define KVM_ARM_VM_SMCCC_FILTER 0
 #define KVM_DEV_ARM_VGIC_GRP_ADDR 0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
 #define KVM_DEV_ARM_VGIC_GRP_CPU_REGS 2
@@ -237,6 +243,8 @@
 #define KVM_ARM_VCPU_TIMER_CTRL 1
 #define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
 #define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
+#define KVM_ARM_VCPU_TIMER_IRQ_HVTIMER 2
+#define KVM_ARM_VCPU_TIMER_IRQ_HPTIMER 3
 #define KVM_ARM_VCPU_PVTIME_CTRL 2
 #define KVM_ARM_VCPU_PVTIME_IPA 0
 #define KVM_ARM_IRQ_VCPU2_SHIFT 28
@@ -266,5 +274,18 @@
 #define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
 #define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0)
 #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
+enum kvm_smccc_filter_action {
+  KVM_SMCCC_FILTER_HANDLE = 0,
+  KVM_SMCCC_FILTER_DENY,
+  KVM_SMCCC_FILTER_FWD_TO_USER,
+};
+struct kvm_smccc_filter {
+  __u32 base;
+  __u32 nr_functions;
+  __u8 action;
+  __u8 pad[15];
+};
+#define KVM_HYPERCALL_EXIT_SMC (1U << 0)
+#define KVM_HYPERCALL_EXIT_16BIT (1U << 1)
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-generic/fcntl.h b/libc/kernel/uapi/asm-generic/fcntl.h
index ea8c108..84c0481 100644
--- a/libc/kernel/uapi/asm-generic/fcntl.h
+++ b/libc/kernel/uapi/asm-generic/fcntl.h
@@ -78,7 +78,6 @@
 #define __O_TMPFILE 020000000
 #endif
 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
-#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
 #ifndef O_NDELAY
 #define O_NDELAY O_NONBLOCK
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
new file mode 100644
index 0000000..0722805
--- /dev/null
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_ASM_HWPROBE_H
+#define _UAPI_ASM_HWPROBE_H
+#include <linux/types.h>
+struct riscv_hwprobe {
+  __s64 key;
+  __u64 value;
+};
+#define RISCV_HWPROBE_KEY_MVENDORID 0
+#define RISCV_HWPROBE_KEY_MARCHID 1
+#define RISCV_HWPROBE_KEY_MIMPID 2
+#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
+#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
+#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
+#define RISCV_HWPROBE_IMA_FD (1 << 0)
+#define RISCV_HWPROBE_IMA_C (1 << 1)
+#define RISCV_HWPROBE_KEY_CPUPERF_0 5
+#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
+#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
+#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
+#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
+#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
+#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
+#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
index b49e3a0..bc7baef 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -20,6 +20,7 @@
 #define __LINUX_KVM_RISCV_H
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+#include <asm/bitsperlong.h>
 #include <asm/ptrace.h>
 #define __KVM_HAVE_READONLY_MEM
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -43,6 +44,7 @@
   unsigned long mvendorid;
   unsigned long marchid;
   unsigned long mimpid;
+  unsigned long zicboz_block_size;
 };
 struct kvm_riscv_core {
   struct user_regs_struct regs;
@@ -62,6 +64,15 @@
   unsigned long satp;
   unsigned long scounteren;
 };
+struct kvm_riscv_aia_csr {
+  unsigned long siselect;
+  unsigned long iprio1;
+  unsigned long iprio2;
+  unsigned long sieh;
+  unsigned long siph;
+  unsigned long iprio1h;
+  unsigned long iprio2h;
+};
 struct kvm_riscv_timer {
   __u64 frequency;
   __u64 time;
@@ -81,19 +92,39 @@
   KVM_RISCV_ISA_EXT_SVINVAL,
   KVM_RISCV_ISA_EXT_ZIHINTPAUSE,
   KVM_RISCV_ISA_EXT_ZICBOM,
+  KVM_RISCV_ISA_EXT_ZICBOZ,
+  KVM_RISCV_ISA_EXT_ZBB,
+  KVM_RISCV_ISA_EXT_SSAIA,
   KVM_RISCV_ISA_EXT_MAX,
 };
+enum KVM_RISCV_SBI_EXT_ID {
+  KVM_RISCV_SBI_EXT_V01 = 0,
+  KVM_RISCV_SBI_EXT_TIME,
+  KVM_RISCV_SBI_EXT_IPI,
+  KVM_RISCV_SBI_EXT_RFENCE,
+  KVM_RISCV_SBI_EXT_SRST,
+  KVM_RISCV_SBI_EXT_HSM,
+  KVM_RISCV_SBI_EXT_PMU,
+  KVM_RISCV_SBI_EXT_EXPERIMENTAL,
+  KVM_RISCV_SBI_EXT_VENDOR,
+  KVM_RISCV_SBI_EXT_MAX,
+};
 #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))
 #define KVM_REG_RISCV_TYPE_MASK 0x00000000FF000000
 #define KVM_REG_RISCV_TYPE_SHIFT 24
+#define KVM_REG_RISCV_SUBTYPE_MASK 0x0000000000FF0000
+#define KVM_REG_RISCV_SUBTYPE_SHIFT 16
 #define KVM_REG_RISCV_CONFIG (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_CONFIG_REG(name) (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_CORE (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_CORE_REG(name) (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
 #define KVM_REG_RISCV_CSR_REG(name) (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
+#define KVM_REG_RISCV_CSR_AIA_REG(name) (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long))
 #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_TIMER_REG(name) (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
 #define KVM_REG_RISCV_FP_F (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
@@ -101,5 +132,12 @@
 #define KVM_REG_RISCV_FP_D (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
 #define KVM_REG_RISCV_FP_D_REG(name) (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
 #define KVM_REG_RISCV_ISA_EXT (0x07 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_EXT (0x08 << KVM_REG_RISCV_TYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_SINGLE (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_EN (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_DIS (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT)
+#define KVM_REG_RISCV_SBI_MULTI_REG(__ext_id) ((__ext_id) / __BITS_PER_LONG)
+#define KVM_REG_RISCV_SBI_MULTI_MASK(__ext_id) (1UL << ((__ext_id) % __BITS_PER_LONG))
+#define KVM_REG_RISCV_SBI_MULTI_REG_LAST KVM_REG_RISCV_SBI_MULTI_REG(KVM_RISCV_SBI_EXT_MAX - 1)
 #endif
 #endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/unistd.h b/libc/kernel/uapi/asm-riscv/asm/unistd.h
index 665b820..b321ead 100644
--- a/libc/kernel/uapi/asm-riscv/asm/unistd.h
+++ b/libc/kernel/uapi/asm-riscv/asm/unistd.h
@@ -27,3 +27,7 @@
 #define __NR_riscv_flush_icache (__NR_arch_specific_syscall + 15)
 #endif
 __SYSCALL(__NR_riscv_flush_icache, sys_riscv_flush_icache)
+#ifndef __NR_riscv_hwprobe
+#define __NR_riscv_hwprobe (__NR_arch_specific_syscall + 14)
+#endif
+__SYSCALL(__NR_riscv_hwprobe, sys_riscv_hwprobe)
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 5c8f5a6..105a8e1 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -420,4 +420,5 @@
 #define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56)
 #define KVM_VCPU_TSC_CTRL 0
 #define KVM_VCPU_TSC_OFFSET 0
+#define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0)
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/prctl.h b/libc/kernel/uapi/asm-x86/asm/prctl.h
index c5ba2d6..e2fe9df 100644
--- a/libc/kernel/uapi/asm-x86/asm/prctl.h
+++ b/libc/kernel/uapi/asm-x86/asm/prctl.h
@@ -29,7 +29,13 @@
 #define ARCH_REQ_XCOMP_PERM 0x1023
 #define ARCH_GET_XCOMP_GUEST_PERM 0x1024
 #define ARCH_REQ_XCOMP_GUEST_PERM 0x1025
+#define ARCH_XCOMP_TILECFG 17
+#define ARCH_XCOMP_TILEDATA 18
 #define ARCH_MAP_VDSO_X32 0x2001
 #define ARCH_MAP_VDSO_32 0x2002
 #define ARCH_MAP_VDSO_64 0x2003
+#define ARCH_GET_UNTAG_MASK 0x4001
+#define ARCH_ENABLE_TAGGED_ADDR 0x4002
+#define ARCH_GET_MAX_TAG_BITS 0x4003
+#define ARCH_FORCE_TAGGED_SVA 0x4004
 #endif
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 0a95afd..759b9e3 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -83,6 +83,10 @@
 #define X86_CR3_PCD _BITUL(X86_CR3_PCD_BIT)
 #define X86_CR3_PCID_BITS 12
 #define X86_CR3_PCID_MASK (_AC((1UL << X86_CR3_PCID_BITS) - 1, UL))
+#define X86_CR3_LAM_U57_BIT 61
+#define X86_CR3_LAM_U57 _BITULL(X86_CR3_LAM_U57_BIT)
+#define X86_CR3_LAM_U48_BIT 62
+#define X86_CR3_LAM_U48 _BITULL(X86_CR3_LAM_U48_BIT)
 #define X86_CR3_PCID_NOFLUSH_BIT 63
 #define X86_CR3_PCID_NOFLUSH _BITULL(X86_CR3_PCID_NOFLUSH_BIT)
 #define X86_CR4_VME_BIT 0
@@ -129,6 +133,8 @@
 #define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT)
 #define X86_CR4_CET_BIT 23
 #define X86_CR4_CET _BITUL(X86_CR4_CET_BIT)
+#define X86_CR4_LAM_SUP_BIT 28
+#define X86_CR4_LAM_SUP _BITUL(X86_CR4_LAM_SUP_BIT)
 #define X86_CR8_TPR _AC(0x0000000f, UL)
 #define CX86_PCR0 0x20
 #define CX86_GCR 0xb8
diff --git a/libc/kernel/uapi/drm/habanalabs_accel.h b/libc/kernel/uapi/drm/habanalabs_accel.h
index d7dccef..75ec293 100644
--- a/libc/kernel/uapi/drm/habanalabs_accel.h
+++ b/libc/kernel/uapi/drm/habanalabs_accel.h
@@ -619,7 +619,8 @@
   HL_SERVER_GAUDI_HLS1H = 2,
   HL_SERVER_GAUDI_TYPE1 = 3,
   HL_SERVER_GAUDI_TYPE2 = 4,
-  HL_SERVER_GAUDI2_HLS2 = 5
+  HL_SERVER_GAUDI2_HLS2 = 5,
+  HL_SERVER_GAUDI2_TYPE1 = 7
 };
 #define HL_NOTIFIER_EVENT_TPC_ASSERT (1ULL << 0)
 #define HL_NOTIFIER_EVENT_UNDEFINED_OPCODE (1ULL << 1)
@@ -630,6 +631,8 @@
 #define HL_NOTIFIER_EVENT_GENERAL_HW_ERR (1ULL << 6)
 #define HL_NOTIFIER_EVENT_RAZWI (1ULL << 7)
 #define HL_NOTIFIER_EVENT_PAGE_FAULT (1ULL << 8)
+#define HL_NOTIFIER_EVENT_CRITICL_HW_ERR (1ULL << 9)
+#define HL_NOTIFIER_EVENT_CRITICL_FW_ERR (1ULL << 10)
 #define HL_INFO_HW_IP_INFO 0
 #define HL_INFO_HW_EVENTS 1
 #define HL_INFO_DRAM_USAGE 2
@@ -663,6 +666,8 @@
 #define HL_INFO_PAGE_FAULT_EVENT 33
 #define HL_INFO_USER_MAPPINGS 34
 #define HL_INFO_FW_GENERIC_REQ 35
+#define HL_INFO_HW_ERR_EVENT 36
+#define HL_INFO_FW_ERR_EVENT 37
 #define HL_INFO_VERSION_MAX_LEN 128
 #define HL_INFO_CARD_NAME_MAX_LEN 16
 #define HL_ENGINES_DATA_MAX_SIZE SZ_1M
@@ -692,15 +697,20 @@
   __u64 dram_page_size;
   __u32 edma_enabled_mask;
   __u16 number_of_user_interrupts;
-  __u16 pad2;
-  __u64 reserved4;
+  __u8 reserved1;
+  __u8 reserved2;
+  __u64 reserved3;
   __u64 device_mem_alloc_default_page_size;
+  __u64 reserved4;
   __u64 reserved5;
-  __u64 reserved6;
-  __u32 reserved7;
-  __u8 reserved8;
+  __u32 reserved6;
+  __u8 reserved7;
   __u8 revision_id;
-  __u8 pad[2];
+  __u16 tpc_interrupt_id;
+  __u32 rotator_enabled_mask;
+  __u32 reserved9;
+  __u64 engine_core_interrupt_reg_addr;
+  __u64 reserved_dram_size;
 };
 struct hl_info_dram_usage {
   __u64 dram_free_mem;
@@ -821,6 +831,21 @@
   __u32 engine_id;
   __u32 stream_id;
 };
+struct hl_info_hw_err_event {
+  __s64 timestamp;
+  __u16 event_id;
+  __u16 pad[3];
+};
+enum hl_info_fw_err_type {
+  HL_INFO_FW_HEARTBEAT_ERR,
+  HL_INFO_FW_REPORTED_ERR,
+};
+struct hl_info_fw_err_event {
+  __s64 timestamp;
+  __u16 err_type;
+  __u16 event_id;
+  __u32 pad;
+};
 struct hl_info_dev_memalloc_page_sizes {
   __u64 page_order_bitmask;
 };
@@ -938,10 +963,16 @@
 #define HL_CS_FLAGS_UNRESERVE_SIGNALS_ONLY 0x2000
 #define HL_CS_FLAGS_ENGINE_CORE_COMMAND 0x4000
 #define HL_CS_FLAGS_FLUSH_PCI_HBW_WRITES 0x8000
+#define HL_CS_FLAGS_ENGINES_COMMAND 0x10000
 #define HL_CS_STATUS_SUCCESS 0
 #define HL_MAX_JOBS_PER_CS 512
-#define HL_ENGINE_CORE_HALT (1 << 0)
-#define HL_ENGINE_CORE_RUN (1 << 1)
+enum hl_engine_command {
+  HL_ENGINE_CORE_HALT = 1,
+  HL_ENGINE_CORE_RUN = 2,
+  HL_ENGINE_STALL = 3,
+  HL_ENGINE_RESUME = 4,
+  HL_ENGINE_COMMAND_MAX
+};
 struct hl_cs_in {
   union {
     struct {
@@ -953,6 +984,11 @@
       __u32 num_engine_cores;
       __u32 core_command;
     };
+    struct {
+      __u64 engines;
+      __u32 num_engines;
+      __u32 engine_command;
+    };
   };
   union {
     __u64 seq;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index 794e784..afaa52f 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -797,7 +797,7 @@
 #define I915_CONTEXT_ENGINES_EXT_LOAD_BALANCE 0
 #define I915_CONTEXT_ENGINES_EXT_BOND 1
 #define I915_CONTEXT_ENGINES_EXT_PARALLEL_SUBMIT 2
-  struct i915_engine_class_instance engines[0];
+  struct i915_engine_class_instance engines[];
 } __attribute__((packed));
 #define I915_DEFINE_CONTEXT_PARAM_ENGINES(name__,N__) struct { __u64 extensions; struct i915_engine_class_instance engines[N__]; \
 } __attribute__((packed)) name__
@@ -849,6 +849,8 @@
   I915_OA_FORMAT_A32u40_A4u32_B8_C8,
   I915_OAR_FORMAT_A32u40_A4u32_B8_C8,
   I915_OA_FORMAT_A24u40_A14u32_B8_C8,
+  I915_OAM_FORMAT_MPEC8u64_B8_C8,
+  I915_OAM_FORMAT_MPEC8u32_B8_C8,
   I915_OA_FORMAT_MAX
 };
 enum drm_i915_perf_property_id {
@@ -860,6 +862,8 @@
   DRM_I915_PERF_PROP_HOLD_PREEMPTION,
   DRM_I915_PERF_PROP_GLOBAL_SSEU,
   DRM_I915_PERF_PROP_POLL_OA_PERIOD,
+  DRM_I915_PERF_PROP_OA_ENGINE_CLASS,
+  DRM_I915_PERF_PROP_OA_ENGINE_INSTANCE,
   DRM_I915_PERF_PROP_MAX
 };
 struct drm_i915_perf_open_param {
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index f5a4627..317796d 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -85,7 +85,8 @@
 #define MSM_PREP_READ 0x01
 #define MSM_PREP_WRITE 0x02
 #define MSM_PREP_NOSYNC 0x04
-#define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC)
+#define MSM_PREP_BOOST 0x08
+#define MSM_PREP_FLAGS (MSM_PREP_READ | MSM_PREP_WRITE | MSM_PREP_NOSYNC | MSM_PREP_BOOST | 0)
 struct drm_msm_gem_cpu_prep {
   __u32 handle;
   __u32 op;
@@ -96,7 +97,11 @@
 };
 struct drm_msm_gem_submit_reloc {
   __u32 submit_offset;
+#ifdef __cplusplus
+  __u32 _or;
+#else
   __u32 or;
+#endif
   __s32 shift;
   __u32 reloc_idx;
   __u64 reloc_offset;
@@ -154,9 +159,11 @@
   __u32 syncobj_stride;
   __u32 pad;
 };
+#define MSM_WAIT_FENCE_BOOST 0x00000001
+#define MSM_WAIT_FENCE_FLAGS (MSM_WAIT_FENCE_BOOST | 0)
 struct drm_msm_wait_fence {
   __u32 fence;
-  __u32 pad;
+  __u32 flags;
   struct drm_msm_timespec timeout;
   __u32 queueid;
 };
diff --git a/libc/kernel/uapi/drm/qaic_accel.h b/libc/kernel/uapi/drm/qaic_accel.h
new file mode 100644
index 0000000..d2a43cf
--- /dev/null
+++ b/libc/kernel/uapi/drm/qaic_accel.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef QAIC_ACCEL_H_
+#define QAIC_ACCEL_H_
+#include "drm.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define QAIC_MANAGE_MAX_MSG_LENGTH SZ_4K
+#define QAIC_SEM_INSYNCFENCE 2
+#define QAIC_SEM_OUTSYNCFENCE 1
+#define QAIC_SEM_NOP 0
+#define QAIC_SEM_INIT 1
+#define QAIC_SEM_INC 2
+#define QAIC_SEM_DEC 3
+#define QAIC_SEM_WAIT_EQUAL 4
+#define QAIC_SEM_WAIT_GT_EQ 5
+#define QAIC_SEM_WAIT_GT_0 6
+#define QAIC_TRANS_UNDEFINED 0
+#define QAIC_TRANS_PASSTHROUGH_FROM_USR 1
+#define QAIC_TRANS_PASSTHROUGH_TO_USR 2
+#define QAIC_TRANS_PASSTHROUGH_FROM_DEV 3
+#define QAIC_TRANS_PASSTHROUGH_TO_DEV 4
+#define QAIC_TRANS_DMA_XFER_FROM_USR 5
+#define QAIC_TRANS_DMA_XFER_TO_DEV 6
+#define QAIC_TRANS_ACTIVATE_FROM_USR 7
+#define QAIC_TRANS_ACTIVATE_FROM_DEV 8
+#define QAIC_TRANS_ACTIVATE_TO_DEV 9
+#define QAIC_TRANS_DEACTIVATE_FROM_USR 10
+#define QAIC_TRANS_DEACTIVATE_FROM_DEV 11
+#define QAIC_TRANS_STATUS_FROM_USR 12
+#define QAIC_TRANS_STATUS_TO_USR 13
+#define QAIC_TRANS_STATUS_FROM_DEV 14
+#define QAIC_TRANS_STATUS_TO_DEV 15
+#define QAIC_TRANS_TERMINATE_FROM_DEV 16
+#define QAIC_TRANS_TERMINATE_TO_DEV 17
+#define QAIC_TRANS_DMA_XFER_CONT 18
+#define QAIC_TRANS_VALIDATE_PARTITION_FROM_DEV 19
+#define QAIC_TRANS_VALIDATE_PARTITION_TO_DEV 20
+struct qaic_manage_trans_hdr {
+  __u32 type;
+  __u32 len;
+};
+struct qaic_manage_trans_passthrough {
+  struct qaic_manage_trans_hdr hdr;
+  __u8 data[];
+};
+struct qaic_manage_trans_dma_xfer {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 tag;
+  __u32 pad;
+  __u64 addr;
+  __u64 size;
+};
+struct qaic_manage_trans_activate_to_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 queue_size;
+  __u32 eventfd;
+  __u32 options;
+  __u32 pad;
+};
+struct qaic_manage_trans_activate_from_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 status;
+  __u32 dbc_id;
+  __u64 options;
+};
+struct qaic_manage_trans_deactivate {
+  struct qaic_manage_trans_hdr hdr;
+  __u32 dbc_id;
+  __u32 pad;
+};
+struct qaic_manage_trans_status_to_dev {
+  struct qaic_manage_trans_hdr hdr;
+};
+struct qaic_manage_trans_status_from_dev {
+  struct qaic_manage_trans_hdr hdr;
+  __u16 major;
+  __u16 minor;
+  __u32 status;
+  __u64 status_flags;
+};
+struct qaic_manage_msg {
+  __u32 len;
+  __u32 count;
+  __u64 data;
+};
+struct qaic_create_bo {
+  __u64 size;
+  __u32 handle;
+  __u32 pad;
+};
+struct qaic_mmap_bo {
+  __u32 handle;
+  __u32 pad;
+  __u64 offset;
+};
+struct qaic_sem {
+  __u16 val;
+  __u8 index;
+  __u8 presync;
+  __u8 cmd;
+  __u8 flags;
+  __u16 pad;
+};
+struct qaic_attach_slice_entry {
+  __u64 size;
+  struct qaic_sem sem0;
+  struct qaic_sem sem1;
+  struct qaic_sem sem2;
+  struct qaic_sem sem3;
+  __u64 dev_addr;
+  __u64 db_addr;
+  __u32 db_data;
+  __u32 db_len;
+  __u64 offset;
+};
+struct qaic_attach_slice_hdr {
+  __u32 count;
+  __u32 dbc_id;
+  __u32 handle;
+  __u32 dir;
+  __u64 size;
+};
+struct qaic_attach_slice {
+  struct qaic_attach_slice_hdr hdr;
+  __u64 data;
+};
+struct qaic_execute_entry {
+  __u32 handle;
+  __u32 dir;
+};
+struct qaic_partial_execute_entry {
+  __u32 handle;
+  __u32 dir;
+  __u64 resize;
+};
+struct qaic_execute_hdr {
+  __u32 count;
+  __u32 dbc_id;
+};
+struct qaic_execute {
+  struct qaic_execute_hdr hdr;
+  __u64 data;
+};
+struct qaic_wait {
+  __u32 handle;
+  __u32 timeout;
+  __u32 dbc_id;
+  __u32 pad;
+};
+struct qaic_perf_stats_hdr {
+  __u16 count;
+  __u16 pad;
+  __u32 dbc_id;
+};
+struct qaic_perf_stats {
+  struct qaic_perf_stats_hdr hdr;
+  __u64 data;
+};
+struct qaic_perf_stats_entry {
+  __u32 handle;
+  __u32 queue_level_before;
+  __u32 num_queue_element;
+  __u32 submit_latency_us;
+  __u32 device_latency_us;
+  __u32 pad;
+};
+#define DRM_QAIC_MANAGE 0x00
+#define DRM_QAIC_CREATE_BO 0x01
+#define DRM_QAIC_MMAP_BO 0x02
+#define DRM_QAIC_ATTACH_SLICE_BO 0x03
+#define DRM_QAIC_EXECUTE_BO 0x04
+#define DRM_QAIC_PARTIAL_EXECUTE_BO 0x05
+#define DRM_QAIC_WAIT_BO 0x06
+#define DRM_QAIC_PERF_STATS_BO 0x07
+#define DRM_IOCTL_QAIC_MANAGE DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_MANAGE, struct qaic_manage_msg)
+#define DRM_IOCTL_QAIC_CREATE_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_CREATE_BO, struct qaic_create_bo)
+#define DRM_IOCTL_QAIC_MMAP_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_MMAP_BO, struct qaic_mmap_bo)
+#define DRM_IOCTL_QAIC_ATTACH_SLICE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_ATTACH_SLICE_BO, struct qaic_attach_slice)
+#define DRM_IOCTL_QAIC_EXECUTE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_EXECUTE_BO, struct qaic_execute)
+#define DRM_IOCTL_QAIC_PARTIAL_EXECUTE_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_PARTIAL_EXECUTE_BO, struct qaic_execute)
+#define DRM_IOCTL_QAIC_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_QAIC_WAIT_BO, struct qaic_wait)
+#define DRM_IOCTL_QAIC_PERF_STATS_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_QAIC_PERF_STATS_BO, struct qaic_perf_stats)
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 4131ce4..ff84aea 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -204,6 +204,7 @@
   BPF_PROG_TYPE_LSM,
   BPF_PROG_TYPE_SK_LOOKUP,
   BPF_PROG_TYPE_SYSCALL,
+  BPF_PROG_TYPE_NETFILTER,
 };
 enum bpf_attach_type {
   BPF_CGROUP_INET_INGRESS,
@@ -250,6 +251,8 @@
   BPF_PERF_EVENT,
   BPF_TRACE_KPROBE_MULTI,
   BPF_LSM_CGROUP,
+  BPF_STRUCT_OPS,
+  BPF_NETFILTER,
   __MAX_BPF_ATTACH_TYPE
 };
 #define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -264,6 +267,7 @@
   BPF_LINK_TYPE_PERF_EVENT = 7,
   BPF_LINK_TYPE_KPROBE_MULTI = 8,
   BPF_LINK_TYPE_STRUCT_OPS = 9,
+  BPF_LINK_TYPE_NETFILTER = 10,
   MAX_BPF_LINK_TYPE,
 };
 #define BPF_F_ALLOW_OVERRIDE (1U << 0)
@@ -305,6 +309,7 @@
   BPF_F_MMAPABLE = (1U << 10),
   BPF_F_PRESERVE_ELEMS = (1U << 11),
   BPF_F_INNER_MAP = (1U << 12),
+  BPF_F_LINK = (1U << 13),
 };
 #define BPF_F_QUERY_EFFECTIVE (1U << 0)
 #define BPF_F_TEST_RUN_ON_CPU (1U << 0)
@@ -392,6 +397,7 @@
     __aligned_u64 fd_array;
     __aligned_u64 core_relos;
     __u32 core_relo_rec_size;
+    __u32 log_true_size;
   };
   struct {
     __aligned_u64 pathname;
@@ -457,6 +463,7 @@
     __u32 btf_size;
     __u32 btf_log_size;
     __u32 btf_log_level;
+    __u32 btf_log_true_size;
   };
   struct {
     __u32 pid;
@@ -470,7 +477,10 @@
     __u64 probe_addr;
   } task_fd_query;
   struct {
-    __u32 prog_fd;
+    union {
+      __u32 prog_fd;
+      __u32 map_fd;
+    };
     union {
       __u32 target_fd;
       __u32 target_ifindex;
@@ -497,13 +507,25 @@
         __u32 target_btf_id;
         __u64 cookie;
       } tracing;
+      struct {
+        __u32 pf;
+        __u32 hooknum;
+        __s32 priority;
+        __u32 flags;
+      } netfilter;
     };
   } link_create;
   struct {
     __u32 link_fd;
-    __u32 new_prog_fd;
+    union {
+      __u32 new_prog_fd;
+      __u32 new_map_fd;
+    };
     __u32 flags;
-    __u32 old_prog_fd;
+    union {
+      __u32 old_prog_fd;
+      __u32 old_map_fd;
+    };
   } link_update;
   struct {
     __u32 link_fd;
@@ -954,6 +976,15 @@
     struct {
       __u32 ifindex;
     } xdp;
+    struct {
+      __u32 map_id;
+    } struct_ops;
+    struct {
+      __u32 pf;
+      __u32 hooknum;
+      __s32 priority;
+      __u32 flags;
+    } netfilter;
   };
 } __attribute__((aligned(8)));
 struct bpf_sock_addr {
@@ -1232,6 +1263,9 @@
   __u64 : 64;
   __u64 : 64;
 } __attribute__((aligned(8)));
+struct bpf_refcount {
+  __u32 : 32;
+} __attribute__((aligned(4)));
 struct bpf_sysctl {
   __u32 write;
   __u32 file_pos;
@@ -1297,4 +1331,10 @@
   __u32 access_str_off;
   enum bpf_core_relo_kind kind;
 };
+enum {
+  BPF_F_TIMER_ABS = (1ULL << 0),
+};
+struct bpf_iter_num {
+  __u64 __opaque[1];
+} __attribute__((aligned(8)));
 #endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 5220647..9a7a6fa 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -107,6 +107,7 @@
   __u64 unverified_errors;
 };
 #define BTRFS_SCRUB_READONLY 1
+#define BTRFS_SCRUB_SUPPORTED_FLAGS (BTRFS_SCRUB_READONLY)
 struct btrfs_ioctl_scrub_args {
   __u64 devid;
   __u64 start;
diff --git a/libc/kernel/uapi/linux/cm4000_cs.h b/libc/kernel/uapi/linux/cm4000_cs.h
deleted file mode 100644
index 41b7aa7..0000000
--- a/libc/kernel/uapi/linux/cm4000_cs.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _UAPI_CM4000_H_
-#define _UAPI_CM4000_H_
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#define MAX_ATR 33
-#define CM4000_MAX_DEV 4
-typedef struct atreq {
-  __s32 atr_len;
-  unsigned char atr[64];
-  __s32 power_act;
-  unsigned char bIFSD;
-  unsigned char bIFSC;
-} atreq_t;
-typedef struct ptsreq {
-  __u32 protocol;
-  unsigned char flags;
-  unsigned char pts1;
-  unsigned char pts2;
-  unsigned char pts3;
-} ptsreq_t;
-#define CM_IOC_MAGIC 'c'
-#define CM_IOC_MAXNR 255
-#define CM_IOCGSTATUS _IOR(CM_IOC_MAGIC, 0, unsigned char *)
-#define CM_IOCGATR _IOWR(CM_IOC_MAGIC, 1, atreq_t *)
-#define CM_IOCSPTS _IOW(CM_IOC_MAGIC, 2, ptsreq_t *)
-#define CM_IOCSRDR _IO(CM_IOC_MAGIC, 3)
-#define CM_IOCARDOFF _IO(CM_IOC_MAGIC, 4)
-#define CM_IOSDBGLVL _IOW(CM_IOC_MAGIC, 250, int *)
-#define CM_CARD_INSERTED 0x01
-#define CM_CARD_POWERED 0x02
-#define CM_ATR_PRESENT 0x04
-#define CM_ATR_VALID 0x08
-#define CM_STATE_VALID 0x0f
-#define CM_NO_READER 0x10
-#define CM_BAD_CARD 0x20
-#endif
diff --git a/libc/kernel/uapi/linux/const.h b/libc/kernel/uapi/linux/const.h
index c62a702..d83caad 100644
--- a/libc/kernel/uapi/linux/const.h
+++ b/libc/kernel/uapi/linux/const.h
@@ -30,7 +30,7 @@
 #define _ULL(x) (_AC(x, ULL))
 #define _BITUL(x) (_UL(1) << (x))
 #define _BITULL(x) (_ULL(1) << (x))
-#define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (typeof(x)) (a) - 1)
+#define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (__typeof__(x)) (a) - 1)
 #define __ALIGN_KERNEL_MASK(x,mask) (((x) + (mask)) & ~(mask))
 #define __KERNEL_DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 #endif
diff --git a/libc/kernel/uapi/linux/cxl_mem.h b/libc/kernel/uapi/linux/cxl_mem.h
index 5a0a34e..a45ab14 100644
--- a/libc/kernel/uapi/linux/cxl_mem.h
+++ b/libc/kernel/uapi/linux/cxl_mem.h
@@ -21,19 +21,27 @@
 #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"), ___C(GET_POISON, "Get Poison List"), ___C(INJECT_POISON, "Inject Poison"), ___C(CLEAR_POISON, "Clear Poison"), ___C(GET_SCAN_MEDIA_CAPS, "Get Scan Media Capabilities"), ___C(SCAN_MEDIA, "Scan Media"), ___C(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(MAX, "invalid / last command")
 #define ___C(a,b) CXL_MEM_COMMAND_ID_ ##a
+#define ___DEPRECATED(a,b) CXL_MEM_DEPRECATED_ID_ ##a
 enum {
   CXL_CMDS
 };
 #undef ___C
+#undef ___DEPRECATED
 #define ___C(a,b) { b }
+#define ___DEPRECATED(a,b) { "Deprecated " b }
 static const struct {
   const char * name;
 } cxl_command_names[] __attribute__((__unused__)) = {
   CXL_CMDS
 };
 #undef ___C
+#undef ___DEPRECATED
+#define ___C(a,b) (0)
+#define ___DEPRECATED(a,b) (1)
+#undef ___C
+#undef ___DEPRECATED
 struct cxl_command_info {
   __u32 id;
   __u32 flags;
diff --git a/libc/kernel/uapi/linux/dlm_netlink.h b/libc/kernel/uapi/linux/dlm_netlink.h
deleted file mode 100644
index 0c655fa..0000000
--- a/libc/kernel/uapi/linux/dlm_netlink.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- ***   This header was automatically generated from a Linux kernel header
- ***   of the same name, to make information necessary for userspace to
- ***   call into the kernel available to libc.  It contains only constants,
- ***   structures, and macros generated from the original header, and thus,
- ***   contains no copyrightable information.
- ***
- ***   To edit the content of this header, modify the corresponding
- ***   source file (e.g. under external/kernel-headers/original/) then
- ***   run bionic/libc/kernel/tools/update_all.py
- ***
- ***   Any manual change here will be lost the next time this script will
- ***   be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _DLM_NETLINK_H
-#define _DLM_NETLINK_H
-#include <linux/types.h>
-#include <linux/dlmconstants.h>
-enum {
-  DLM_STATUS_WAITING = 1,
-  DLM_STATUS_GRANTED = 2,
-  DLM_STATUS_CONVERT = 3,
-};
-#define DLM_LOCK_DATA_VERSION 1
-struct dlm_lock_data {
-  __u16 version;
-  __u32 lockspace_id;
-  int nodeid;
-  int ownpid;
-  __u32 id;
-  __u32 remid;
-  __u64 xid;
-  __s8 status;
-  __s8 grmode;
-  __s8 rqmode;
-  unsigned long timestamp;
-  int resource_namelen;
-  char resource_name[DLM_RESNAME_MAXLEN];
-};
-enum {
-  DLM_CMD_UNSPEC = 0,
-  DLM_CMD_HELLO,
-  DLM_CMD_TIMEOUT,
-  __DLM_CMD_MAX,
-};
-#define DLM_CMD_MAX (__DLM_CMD_MAX - 1)
-enum {
-  DLM_TYPE_UNSPEC = 0,
-  DLM_TYPE_LOCK,
-  __DLM_TYPE_MAX,
-};
-#define DLM_TYPE_MAX (__DLM_TYPE_MAX - 1)
-#define DLM_GENL_VERSION 0x1
-#define DLM_GENL_NAME "DLM"
-#endif
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index f0ff78c..76e331f 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -106,9 +106,9 @@
 #define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 #define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 47
+#define DM_VERSION_MINOR 48
 #define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2022-07-28)"
+#define DM_VERSION_EXTRA "-ioctl(2023-03-01)"
 #define DM_READONLY_FLAG (1 << 0)
 #define DM_SUSPEND_FLAG (1 << 1)
 #define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/ethtool_netlink.h b/libc/kernel/uapi/linux/ethtool_netlink.h
index f1ef896..246ab8a 100644
--- a/libc/kernel/uapi/linux/ethtool_netlink.h
+++ b/libc/kernel/uapi/linux/ethtool_netlink.h
@@ -277,6 +277,8 @@
   ETHTOOL_A_RINGS_CQE_SIZE,
   ETHTOOL_A_RINGS_TX_PUSH,
   ETHTOOL_A_RINGS_RX_PUSH,
+  ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
+  ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
   __ETHTOOL_A_RINGS_CNT,
   ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
 };
@@ -576,7 +578,7 @@
   ETHTOOL_A_STATS_GRP_HIST_BKT_HI,
   ETHTOOL_A_STATS_GRP_HIST_VAL,
   __ETHTOOL_A_STATS_GRP_CNT,
-  ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_CNT - 1)
+  ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1)
 };
 enum {
   ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR,
diff --git a/libc/kernel/uapi/linux/ext4.h b/libc/kernel/uapi/linux/ext4.h
new file mode 100644
index 0000000..70a3b1a
--- /dev/null
+++ b/libc/kernel/uapi/linux/ext4.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_EXT4_H
+#define _UAPI_LINUX_EXT4_H
+#include <linux/fiemap.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define EXT4_IOC_GETVERSION _IOR('f', 3, long)
+#define EXT4_IOC_SETVERSION _IOW('f', 4, long)
+#define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION
+#define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION
+#define EXT4_IOC_GETRSVSZ _IOR('f', 5, long)
+#define EXT4_IOC_SETRSVSZ _IOW('f', 6, long)
+#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+#define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input)
+#define EXT4_IOC_MIGRATE _IO('f', 9)
+#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12)
+#define EXT4_IOC_MOVE_EXT _IOWR('f', 15, struct move_extent)
+#define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64)
+#define EXT4_IOC_SWAP_BOOT _IO('f', 17)
+#define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18)
+#define EXT4_IOC_CLEAR_ES_CACHE _IO('f', 40)
+#define EXT4_IOC_GETSTATE _IOW('f', 41, __u32)
+#define EXT4_IOC_GET_ES_CACHE _IOWR('f', 42, struct fiemap)
+#define EXT4_IOC_CHECKPOINT _IOW('f', 43, __u32)
+#define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid)
+#define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid)
+#define EXT4_IOC_SHUTDOWN _IOR('X', 125, __u32)
+#define EXT4_IOC32_GETVERSION _IOR('f', 3, int)
+#define EXT4_IOC32_SETVERSION _IOW('f', 4, int)
+#define EXT4_IOC32_GETRSVSZ _IOR('f', 5, int)
+#define EXT4_IOC32_SETRSVSZ _IOW('f', 6, int)
+#define EXT4_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int)
+#define EXT4_IOC32_GROUP_ADD _IOW('f', 8, struct compat_ext4_new_group_input)
+#define EXT4_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION
+#define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION
+#define EXT4_STATE_FLAG_EXT_PRECACHED 0x00000001
+#define EXT4_STATE_FLAG_NEW 0x00000002
+#define EXT4_STATE_FLAG_NEWENTRY 0x00000004
+#define EXT4_STATE_FLAG_DA_ALLOC_CLOSE 0x00000008
+#define EXT4_IOC_CHECKPOINT_FLAG_DISCARD 0x1
+#define EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT 0x2
+#define EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN 0x4
+#define EXT4_IOC_CHECKPOINT_FLAG_VALID (EXT4_IOC_CHECKPOINT_FLAG_DISCARD | EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT | EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN)
+struct fsuuid {
+  __u32 fsu_len;
+  __u32 fsu_flags;
+  __u8 fsu_uuid[];
+};
+struct move_extent {
+  __u32 reserved;
+  __u32 donor_fd;
+  __u64 orig_start;
+  __u64 donor_start;
+  __u64 len;
+  __u64 moved_len;
+};
+#define EXT4_GOING_FLAGS_DEFAULT 0x0
+#define EXT4_GOING_FLAGS_LOGFLUSH 0x1
+#define EXT4_GOING_FLAGS_NOLOGFLUSH 0x2
+struct ext4_new_group_input {
+  __u32 group;
+  __u64 block_bitmap;
+  __u64 inode_bitmap;
+  __u64 inode_table;
+  __u32 blocks_count;
+  __u16 reserved_blocks;
+  __u16 unused;
+};
+#define EXT4_FIEMAP_EXTENT_HOLE 0x08000000
+#endif
diff --git a/libc/kernel/uapi/linux/gsmmux.h b/libc/kernel/uapi/linux/gsmmux.h
index 6ddf1b9..8ff29fd 100644
--- a/libc/kernel/uapi/linux/gsmmux.h
+++ b/libc/kernel/uapi/linux/gsmmux.h
@@ -49,8 +49,20 @@
 #define GSMIOC_GETFIRST _IOR('G', 4, __u32)
 struct gsm_config_ext {
   __u32 keep_alive;
-  __u32 reserved[7];
+  __u32 wait_config;
+  __u32 reserved[6];
 };
 #define GSMIOC_GETCONF_EXT _IOR('G', 5, struct gsm_config_ext)
 #define GSMIOC_SETCONF_EXT _IOW('G', 6, struct gsm_config_ext)
+struct gsm_dlci_config {
+  __u32 channel;
+  __u32 adaption;
+  __u32 mtu;
+  __u32 priority;
+  __u32 i;
+  __u32 k;
+  __u32 reserved[8];
+};
+#define GSMIOC_GETCONF_DLCI _IOWR('G', 7, struct gsm_dlci_config)
+#define GSMIOC_SETCONF_DLCI _IOW('G', 8, struct gsm_dlci_config)
 #endif
diff --git a/libc/kernel/uapi/linux/handshake.h b/libc/kernel/uapi/linux/handshake.h
new file mode 100644
index 0000000..e9923ae
--- /dev/null
+++ b/libc/kernel/uapi/linux/handshake.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_HANDSHAKE_H
+#define _UAPI_LINUX_HANDSHAKE_H
+#define HANDSHAKE_FAMILY_NAME "handshake"
+#define HANDSHAKE_FAMILY_VERSION 1
+enum handshake_handler_class {
+  HANDSHAKE_HANDLER_CLASS_NONE,
+  HANDSHAKE_HANDLER_CLASS_TLSHD,
+  HANDSHAKE_HANDLER_CLASS_MAX,
+};
+enum handshake_msg_type {
+  HANDSHAKE_MSG_TYPE_UNSPEC,
+  HANDSHAKE_MSG_TYPE_CLIENTHELLO,
+  HANDSHAKE_MSG_TYPE_SERVERHELLO,
+};
+enum handshake_auth {
+  HANDSHAKE_AUTH_UNSPEC,
+  HANDSHAKE_AUTH_UNAUTH,
+  HANDSHAKE_AUTH_PSK,
+  HANDSHAKE_AUTH_X509,
+};
+enum {
+  HANDSHAKE_A_X509_CERT = 1,
+  HANDSHAKE_A_X509_PRIVKEY,
+  __HANDSHAKE_A_X509_MAX,
+  HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1)
+};
+enum {
+  HANDSHAKE_A_ACCEPT_SOCKFD = 1,
+  HANDSHAKE_A_ACCEPT_HANDLER_CLASS,
+  HANDSHAKE_A_ACCEPT_MESSAGE_TYPE,
+  HANDSHAKE_A_ACCEPT_TIMEOUT,
+  HANDSHAKE_A_ACCEPT_AUTH_MODE,
+  HANDSHAKE_A_ACCEPT_PEER_IDENTITY,
+  HANDSHAKE_A_ACCEPT_CERTIFICATE,
+  HANDSHAKE_A_ACCEPT_PEERNAME,
+  __HANDSHAKE_A_ACCEPT_MAX,
+  HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1)
+};
+enum {
+  HANDSHAKE_A_DONE_STATUS = 1,
+  HANDSHAKE_A_DONE_SOCKFD,
+  HANDSHAKE_A_DONE_REMOTE_AUTH,
+  __HANDSHAKE_A_DONE_MAX,
+  HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1)
+};
+enum {
+  HANDSHAKE_CMD_READY = 1,
+  HANDSHAKE_CMD_ACCEPT,
+  HANDSHAKE_CMD_DONE,
+  __HANDSHAKE_CMD_MAX,
+  HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1)
+};
+#define HANDSHAKE_MCGRP_NONE "none"
+#define HANDSHAKE_MCGRP_TLSHD "tlshd"
+#endif
diff --git a/libc/kernel/uapi/linux/hw_breakpoint.h b/libc/kernel/uapi/linux/hw_breakpoint.h
index 74acd53..416d746 100644
--- a/libc/kernel/uapi/linux/hw_breakpoint.h
+++ b/libc/kernel/uapi/linux/hw_breakpoint.h
@@ -36,9 +36,4 @@
   HW_BREAKPOINT_X = 4,
   HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
 };
-enum bp_type_idx {
-  TYPE_INST = 0,
-  TYPE_DATA = 1,
-  TYPE_MAX
-};
 #endif
diff --git a/libc/kernel/uapi/linux/idxd.h b/libc/kernel/uapi/linux/idxd.h
index 01c62f2..f8cfc11 100644
--- a/libc/kernel/uapi/linux/idxd.h
+++ b/libc/kernel/uapi/linux/idxd.h
@@ -39,6 +39,7 @@
   IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
   IDXD_SCMD_WQ_IRQ_ERR = 0x80100000,
   IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000,
+  IDXD_SCMD_DEV_EVL_ERR = 0x80120000,
 };
 #define IDXD_SCMD_SOFTERR_MASK 0x80000000
 #define IDXD_SCMD_SOFTERR_SHIFT 16
@@ -74,12 +75,14 @@
   DSA_OPCODE_CR_DELTA,
   DSA_OPCODE_AP_DELTA,
   DSA_OPCODE_DUALCAST,
+  DSA_OPCODE_TRANSL_FETCH,
   DSA_OPCODE_CRCGEN = 0x10,
   DSA_OPCODE_COPY_CRC,
   DSA_OPCODE_DIF_CHECK,
   DSA_OPCODE_DIF_INS,
   DSA_OPCODE_DIF_STRP,
   DSA_OPCODE_DIF_UPDT,
+  DSA_OPCODE_DIX_GEN = 0x17,
   DSA_OPCODE_CFLUSH = 0x20,
 };
 enum iax_opcode {
@@ -131,6 +134,8 @@
   DSA_COMP_HW_ERR1,
   DSA_COMP_HW_ERR_DRB,
   DSA_COMP_TRANSLATION_FAIL,
+  DSA_COMP_DRAIN_EVL = 0x26,
+  DSA_COMP_BATCH_EVL_ERR,
 };
 enum iax_completion_status {
   IAX_COMP_NONE = 0,
@@ -164,6 +169,7 @@
 };
 #define DSA_COMP_STATUS_MASK 0x7f
 #define DSA_COMP_STATUS_WRITE 0x80
+#define DSA_COMP_STATUS(status) ((status) & DSA_COMP_STATUS_MASK)
 struct dsa_hw_desc {
   uint32_t pasid : 20;
   uint32_t rsvd : 11;
@@ -176,6 +182,8 @@
     uint64_t rdback_addr;
     uint64_t pattern;
     uint64_t desc_list_addr;
+    uint64_t pattern_lower;
+    uint64_t transl_fetch_addr;
   };
   union {
     uint64_t dst_addr;
@@ -186,6 +194,7 @@
   union {
     uint32_t xfer_size;
     uint32_t desc_count;
+    uint32_t region_size;
   };
   uint16_t int_handle;
   uint16_t rsvd1;
@@ -234,6 +243,20 @@
       uint16_t dest_app_tag_mask;
       uint16_t dest_app_tag_seed;
     };
+    uint64_t pattern_upper;
+    struct {
+      uint64_t transl_fetch_res;
+      uint32_t region_stride;
+    };
+    struct {
+      uint8_t dix_gen_res;
+      uint8_t dest_dif_flags;
+      uint8_t dif_flags;
+      uint8_t dix_gen_res2[13];
+      uint32_t ref_tag_seed;
+      uint16_t app_tag_mask;
+      uint16_t app_tag_seed;
+    };
     uint8_t op_specific[24];
   };
 } __attribute__((packed));
@@ -267,8 +290,12 @@
     uint8_t result;
     uint8_t dif_status;
   };
-  uint16_t rsvd;
-  uint32_t bytes_completed;
+  uint8_t fault_info;
+  uint8_t rsvd;
+  union {
+    uint32_t bytes_completed;
+    uint32_t descs_completed;
+  };
   uint64_t fault_addr;
   union {
     struct {
@@ -296,6 +323,12 @@
       uint16_t dif_upd_dest_app_tag_mask;
       uint16_t dif_upd_dest_app_tag;
     };
+    struct {
+      uint64_t dix_gen_res;
+      uint32_t dix_ref_tag;
+      uint16_t dix_app_tag_mask;
+      uint16_t dix_app_tag;
+    };
     uint8_t op_specific[16];
   };
 } __attribute__((packed));
@@ -305,7 +338,8 @@
 struct iax_completion_record {
   volatile uint8_t status;
   uint8_t error_code;
-  uint16_t rsvd;
+  uint8_t fault_info;
+  uint8_t rsvd;
   uint32_t bytes_completed;
   uint64_t fault_addr;
   uint32_t invalid_flags;
diff --git a/libc/kernel/uapi/linux/if_bridge.h b/libc/kernel/uapi/linux/if_bridge.h
index 48f6345..1f90580 100644
--- a/libc/kernel/uapi/linux/if_bridge.h
+++ b/libc/kernel/uapi/linux/if_bridge.h
@@ -437,6 +437,7 @@
   BRIDGE_VLANDB_ENTRY_MCAST_ROUTER,
   BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS,
   BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS,
+  BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS,
   __BRIDGE_VLANDB_ENTRY_MAX,
 };
 #define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
@@ -506,6 +507,11 @@
   MDBA_MDB_EATTR_GROUP_MODE,
   MDBA_MDB_EATTR_SOURCE,
   MDBA_MDB_EATTR_RTPROT,
+  MDBA_MDB_EATTR_DST,
+  MDBA_MDB_EATTR_DST_PORT,
+  MDBA_MDB_EATTR_VNI,
+  MDBA_MDB_EATTR_IFINDEX,
+  MDBA_MDB_EATTR_SRC_VNI,
   __MDBA_MDB_EATTR_MAX
 };
 #define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
@@ -581,6 +587,11 @@
   MDBE_ATTR_SRC_LIST,
   MDBE_ATTR_GROUP_MODE,
   MDBE_ATTR_RTPROT,
+  MDBE_ATTR_DST,
+  MDBE_ATTR_DST_PORT,
+  MDBE_ATTR_VNI,
+  MDBE_ATTR_IFINDEX,
+  MDBE_ATTR_SRC_VNI,
   __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 fbb933b..5b1d66a 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -311,6 +311,7 @@
   IFLA_BRPORT_MAB,
   IFLA_BRPORT_MCAST_N_GROUPS,
   IFLA_BRPORT_MCAST_MAX_GROUPS,
+  IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
   __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
@@ -364,6 +365,7 @@
   IFLA_MACVLAN_MACADDR_COUNT,
   IFLA_MACVLAN_BC_QUEUE_LEN,
   IFLA_MACVLAN_BC_QUEUE_LEN_USED,
+  IFLA_MACVLAN_BC_CUTOFF,
   __IFLA_MACVLAN_MAX,
 };
 #define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
diff --git a/libc/kernel/uapi/linux/if_packet.h b/libc/kernel/uapi/linux/if_packet.h
index 719f596..1fe897a 100644
--- a/libc/kernel/uapi/linux/if_packet.h
+++ b/libc/kernel/uapi/linux/if_packet.h
@@ -65,6 +65,7 @@
 #define PACKET_ROLLOVER_STATS 21
 #define PACKET_FANOUT_DATA 22
 #define PACKET_IGNORE_OUTGOING 23
+#define PACKET_VNET_HDR_SZ 24
 #define PACKET_FANOUT_HASH 0
 #define PACKET_FANOUT_LB 1
 #define PACKET_FANOUT_CPU 2
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index 3947d5a..3e98b79 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -142,6 +142,7 @@
 #define IP_MULTICAST_ALL 49
 #define IP_UNICAST_IF 50
 #define IP_LOCAL_PORT_RANGE 51
+#define IP_PROTOCOL 52
 #define MCAST_EXCLUDE 0
 #define MCAST_INCLUDE 1
 #define IP_DEFAULT_MULTICAST_TTL 1
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index a2d4f5f..b6c396f 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -178,6 +178,7 @@
 #define IORING_TIMEOUT_REALTIME (1U << 3)
 #define IORING_LINK_TIMEOUT_UPDATE (1U << 4)
 #define IORING_TIMEOUT_ETIME_SUCCESS (1U << 5)
+#define IORING_TIMEOUT_MULTISHOT (1U << 6)
 #define IORING_TIMEOUT_CLOCK_MASK (IORING_TIMEOUT_BOOTTIME | IORING_TIMEOUT_REALTIME)
 #define IORING_TIMEOUT_UPDATE_MASK (IORING_TIMEOUT_UPDATE | IORING_LINK_TIMEOUT_UPDATE)
 #define SPLICE_F_FD_IN_FIXED (1U << 31)
@@ -217,6 +218,9 @@
 #define IORING_OFF_SQ_RING 0ULL
 #define IORING_OFF_CQ_RING 0x8000000ULL
 #define IORING_OFF_SQES 0x10000000ULL
+#define IORING_OFF_PBUF_RING 0x80000000ULL
+#define IORING_OFF_PBUF_SHIFT 16
+#define IORING_OFF_MMAP_MASK 0xf8000000ULL
 struct io_sqring_offsets {
   __u32 head;
   __u32 tail;
@@ -334,17 +338,6 @@
   __u32 nr;
   __u32 resv2;
 };
-struct io_uring_notification_slot {
-  __u64 tag;
-  __u64 resv[3];
-};
-struct io_uring_notification_register {
-  __u32 nr_slots;
-  __u32 resv;
-  __u64 resv2;
-  __u64 data;
-  __u64 resv3;
-};
 #define IORING_REGISTER_FILES_SKIP (- 2)
 #define IO_URING_OP_SUPPORTED (1U << 0)
 struct io_uring_probe_op {
@@ -387,11 +380,14 @@
     __DECLARE_FLEX_ARRAY(struct io_uring_buf, bufs);
   };
 };
+enum {
+  IOU_PBUF_RING_MMAP = 1,
+};
 struct io_uring_buf_reg {
   __u64 ring_addr;
   __u32 ring_entries;
   __u16 bgid;
-  __u16 pad;
+  __u16 flags;
   __u64 resv[3];
 };
 enum {
diff --git a/libc/kernel/uapi/linux/ipv6.h b/libc/kernel/uapi/linux/ipv6.h
index d62d269..d8fe3cd 100644
--- a/libc/kernel/uapi/linux/ipv6.h
+++ b/libc/kernel/uapi/linux/ipv6.h
@@ -62,7 +62,7 @@
 struct rt0_hdr {
   struct ipv6_rt_hdr rt_hdr;
   __u32 reserved;
-  struct in6_addr addr[0];
+  struct in6_addr addr[];
 #define rt0_type rt_hdr.type
 };
 struct rt2_hdr {
diff --git a/libc/kernel/uapi/linux/isst_if.h b/libc/kernel/uapi/linux/isst_if.h
index 322f70d..9d03b7a 100644
--- a/libc/kernel/uapi/linux/isst_if.h
+++ b/libc/kernel/uapi/linux/isst_if.h
@@ -67,10 +67,136 @@
   __u32 cmd_count;
   struct isst_if_msr_cmd msr_cmd[1];
 };
+struct isst_core_power {
+  __u8 get_set;
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 enable;
+  __u8 supported;
+  __u8 priority_type;
+};
+struct isst_clos_param {
+  __u8 get_set;
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 clos;
+  __u16 min_freq_mhz;
+  __u16 max_freq_mhz;
+  __u8 prop_prio;
+};
+struct isst_if_clos_assoc {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 logical_cpu;
+  __u16 clos;
+};
+struct isst_if_clos_assoc_cmds {
+  __u16 cmd_count;
+  __u16 get_set;
+  __u16 punit_cpu_map;
+  struct isst_if_clos_assoc assoc_info[1];
+};
+struct isst_tpmi_instance_count {
+  __u8 socket_id;
+  __u8 count;
+  __u16 valid_mask;
+};
+struct isst_perf_level_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 max_level;
+  __u8 feature_rev;
+  __u8 level_mask;
+  __u8 current_level;
+  __u8 feature_state;
+  __u8 locked;
+  __u8 enabled;
+  __u8 sst_tf_support;
+  __u8 sst_bf_support;
+};
+struct isst_perf_level_control {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 level;
+};
+struct isst_perf_feature_control {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 feature;
+};
+#define TRL_MAX_BUCKETS 8
+#define TRL_MAX_LEVELS 6
+struct isst_perf_level_data_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 tdp_ratio;
+  __u16 base_freq_mhz;
+  __u16 base_freq_avx2_mhz;
+  __u16 base_freq_avx512_mhz;
+  __u16 base_freq_amx_mhz;
+  __u16 thermal_design_power_w;
+  __u16 tjunction_max_c;
+  __u16 max_memory_freq_mhz;
+  __u16 cooling_type;
+  __u16 p0_freq_mhz;
+  __u16 p1_freq_mhz;
+  __u16 pn_freq_mhz;
+  __u16 pm_freq_mhz;
+  __u16 p0_fabric_freq_mhz;
+  __u16 p1_fabric_freq_mhz;
+  __u16 pn_fabric_freq_mhz;
+  __u16 pm_fabric_freq_mhz;
+  __u16 max_buckets;
+  __u16 max_trl_levels;
+  __u16 bucket_core_counts[TRL_MAX_BUCKETS];
+  __u16 trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS];
+};
+struct isst_perf_level_cpu_mask {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u8 level;
+  __u8 punit_cpu_map;
+  __u64 mask;
+  __u16 cpu_buffer_size;
+  __s8 cpu_buffer[1];
+};
+struct isst_base_freq_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 high_base_freq_mhz;
+  __u16 low_base_freq_mhz;
+  __u16 tjunction_max_c;
+  __u16 thermal_design_power_w;
+};
+struct isst_turbo_freq_info {
+  __u8 socket_id;
+  __u8 power_domain_id;
+  __u16 level;
+  __u16 max_clip_freqs;
+  __u16 max_buckets;
+  __u16 max_trl_levels;
+  __u16 lp_clip_freq_mhz[TRL_MAX_LEVELS];
+  __u16 bucket_core_counts[TRL_MAX_BUCKETS];
+  __u16 trl_freq_mhz[TRL_MAX_LEVELS][TRL_MAX_BUCKETS];
+};
 #define ISST_IF_MAGIC 0xFE
 #define ISST_IF_GET_PLATFORM_INFO _IOR(ISST_IF_MAGIC, 0, struct isst_if_platform_info *)
 #define ISST_IF_GET_PHY_ID _IOWR(ISST_IF_MAGIC, 1, struct isst_if_cpu_map *)
 #define ISST_IF_IO_CMD _IOW(ISST_IF_MAGIC, 2, struct isst_if_io_regs *)
 #define ISST_IF_MBOX_COMMAND _IOWR(ISST_IF_MAGIC, 3, struct isst_if_mbox_cmds *)
 #define ISST_IF_MSR_COMMAND _IOWR(ISST_IF_MAGIC, 4, struct isst_if_msr_cmds *)
+#define ISST_IF_COUNT_TPMI_INSTANCES _IOR(ISST_IF_MAGIC, 5, struct isst_tpmi_instance_count *)
+#define ISST_IF_CORE_POWER_STATE _IOWR(ISST_IF_MAGIC, 6, struct isst_core_power *)
+#define ISST_IF_CLOS_PARAM _IOWR(ISST_IF_MAGIC, 7, struct isst_clos_param *)
+#define ISST_IF_CLOS_ASSOC _IOWR(ISST_IF_MAGIC, 8, struct isst_if_clos_assoc_cmds *)
+#define ISST_IF_PERF_LEVELS _IOWR(ISST_IF_MAGIC, 9, struct isst_perf_level_info *)
+#define ISST_IF_PERF_SET_LEVEL _IOW(ISST_IF_MAGIC, 10, struct isst_perf_level_control *)
+#define ISST_IF_PERF_SET_FEATURE _IOW(ISST_IF_MAGIC, 11, struct isst_perf_feature_control *)
+#define ISST_IF_GET_PERF_LEVEL_INFO _IOR(ISST_IF_MAGIC, 12, struct isst_perf_level_data_info *)
+#define ISST_IF_GET_PERF_LEVEL_CPU_MASK _IOR(ISST_IF_MAGIC, 13, struct isst_perf_level_cpu_mask *)
+#define ISST_IF_GET_BASE_FREQ_INFO _IOR(ISST_IF_MAGIC, 14, struct isst_base_freq_info *)
+#define ISST_IF_GET_BASE_FREQ_CPU_MASK _IOR(ISST_IF_MAGIC, 15, struct isst_perf_level_cpu_mask *)
+#define ISST_IF_GET_TURBO_FREQ_INFO _IOR(ISST_IF_MAGIC, 16, struct isst_turbo_freq_info *)
 #endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index d21e0fc..9fd0420 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -21,7 +21,7 @@
 #include <drm/drm.h>
 #include <linux/ioctl.h>
 #define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 11
+#define KFD_IOCTL_MINOR_VERSION 12
 struct kfd_ioctl_get_version_args {
   __u32 major_version;
   __u32 minor_version;
@@ -294,6 +294,11 @@
   __u32 gpu_id;
   __u32 dmabuf_fd;
 };
+struct kfd_ioctl_export_dmabuf_args {
+  __u64 handle;
+  __u32 flags;
+  __u32 dmabuf_fd;
+};
 enum kfd_smi_event {
   KFD_SMI_EVENT_NONE = 0,
   KFD_SMI_EVENT_VMFAULT = 1,
@@ -451,6 +456,7 @@
 #define AMDKFD_IOC_SET_XNACK_MODE AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args)
 #define AMDKFD_IOC_CRIU_OP AMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args)
 #define AMDKFD_IOC_AVAILABLE_MEMORY AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)
+#define AMDKFD_IOC_EXPORT_DMABUF AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args)
 #define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x24
+#define AMDKFD_COMMAND_END 0x25
 #endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index 342c5c9..4101587 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -265,8 +265,10 @@
       __u64 nr;
       __u64 args[6];
       __u64 ret;
-      __u32 longmode;
-      __u32 pad;
+      union {
+        __u32 longmode;
+        __u64 flags;
+      };
     } hypercall;
     struct {
       __u64 rip;
@@ -932,6 +934,7 @@
 #define KVM_CAP_S390_PROTECTED_ASYNC_DISABLE 224
 #define KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP 225
 #define KVM_CAP_PMU_EVENT_MASKED_EVENTS 226
+#define KVM_CAP_COUNTER_OFFSET 227
 #ifdef KVM_CAP_IRQ_ROUTING
 struct kvm_irq_routing_irqchip {
   __u32 irqchip;
@@ -1198,6 +1201,7 @@
 #define KVM_SET_PMU_EVENT_FILTER _IOW(KVMIO, 0xb2, struct kvm_pmu_event_filter)
 #define KVM_PPC_SVM_OFF _IO(KVMIO, 0xb3)
 #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags)
+#define KVM_ARM_SET_COUNTER_OFFSET _IOW(KVMIO, 0xb5, struct kvm_arm_counter_offset)
 #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
 #define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr)
 #define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr)
diff --git a/libc/kernel/uapi/linux/mei.h b/libc/kernel/uapi/linux/mei.h
index ed37abd..3d4ae66 100644
--- a/libc/kernel/uapi/linux/mei.h
+++ b/libc/kernel/uapi/linux/mei.h
@@ -18,7 +18,7 @@
  ****************************************************************************/
 #ifndef _LINUX_MEI_H
 #define _LINUX_MEI_H
-#include <linux/uuid.h>
+#include <linux/mei_uuid.h>
 #define IOCTL_MEI_CONNECT_CLIENT _IOWR('H', 0x01, struct mei_connect_client_data)
 struct mei_client {
   __u32 max_msg_length;
diff --git a/libc/kernel/uapi/linux/mei_uuid.h b/libc/kernel/uapi/linux/mei_uuid.h
new file mode 100644
index 0000000..17f6e55
--- /dev/null
+++ b/libc/kernel/uapi/linux/mei_uuid.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_MEI_UUID_H_
+#define _UAPI_LINUX_MEI_UUID_H_
+#include <linux/types.h>
+typedef struct {
+  __u8 b[16];
+} uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((uuid_le) \
+{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+#endif
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index 3b74393..fee4b74 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -51,13 +51,19 @@
 struct nbd_request {
   __be32 magic;
   __be32 type;
-  char handle[8];
+  union {
+    __be64 cookie;
+    char handle[8];
+  };
   __be64 from;
   __be32 len;
 } __attribute__((packed));
 struct nbd_reply {
   __be32 magic;
   __be32 error;
-  char handle[8];
+  union {
+    __be64 cookie;
+    char handle[8];
+  };
 };
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 33bfb7f..1feec33 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -500,6 +500,7 @@
   NFT_META_TIME_HOUR,
   NFT_META_SDIF,
   NFT_META_SDIFNAME,
+  NFT_META_BRI_BROUTE,
   __NFT_META_IIFTYPE,
 };
 enum nft_rt_keys {
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
index ce1692c..702917d 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_hook.h
@@ -50,5 +50,12 @@
 #define NFNLA_CHAIN_MAX (__NFNLA_CHAIN_MAX - 1)
 enum nfnl_hook_chaintype {
   NFNL_HOOK_TYPE_NFTABLES = 0x1,
+  NFNL_HOOK_TYPE_BPF,
 };
+enum nfnl_hook_bpf_attributes {
+  NFNLA_HOOK_BPF_UNSPEC,
+  NFNLA_HOOK_BPF_ID,
+  __NFNLA_HOOK_BPF_MAX,
+};
+#define NFNLA_HOOK_BPF_MAX (__NFNLA_HOOK_BPF_MAX - 1)
 #endif
diff --git a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
index d100dec..c2d62ba 100644
--- a/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/libc/kernel/uapi/linux/netfilter/nfnetlink_queue.h
@@ -71,6 +71,7 @@
   NFQA_VLAN,
   NFQA_L2HDR,
   NFQA_PRIORITY,
+  NFQA_CGROUP_CLASSID,
   __NFQA_MAX
 };
 #define NFQA_MAX (__NFQA_MAX - 1)
diff --git a/libc/kernel/uapi/linux/nfsd/export.h b/libc/kernel/uapi/linux/nfsd/export.h
index 4716fb1..63ccedc 100644
--- a/libc/kernel/uapi/linux/nfsd/export.h
+++ b/libc/kernel/uapi/linux/nfsd/export.h
@@ -41,4 +41,9 @@
 #define NFSEXP_PNFS 0x20000
 #define NFSEXP_ALLFLAGS 0x3FEFF
 #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH | NFSEXP_ALLSQUASH | NFSEXP_INSECURE_PORT)
+#define NFSEXP_XPRTSEC_NONE 0x0001
+#define NFSEXP_XPRTSEC_TLS 0x0002
+#define NFSEXP_XPRTSEC_MTLS 0x0004
+#define NFSEXP_XPRTSEC_NUM (3)
+#define NFSEXP_XPRTSEC_ALL (NFSEXP_XPRTSEC_NONE | NFSEXP_XPRTSEC_TLS | NFSEXP_XPRTSEC_MTLS)
 #endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index d73922a..32ec521 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -190,6 +190,7 @@
   NL80211_CMD_ADD_LINK_STA,
   NL80211_CMD_MODIFY_LINK_STA,
   NL80211_CMD_REMOVE_LINK_STA,
+  NL80211_CMD_SET_HW_TIMESTAMP,
   __NL80211_CMD_AFTER_LAST,
   NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
 };
@@ -529,6 +530,9 @@
   NL80211_ATTR_RX_HW_TIMESTAMP,
   NL80211_ATTR_TD_BITMAP,
   NL80211_ATTR_PUNCT_BITMAP,
+  NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS,
+  NL80211_ATTR_HW_TIMESTAMP_ENABLED,
+  NL80211_ATTR_EMA_RNR_ELEMS,
   __NL80211_ATTR_AFTER_LAST,
   NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
   NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -822,6 +826,8 @@
   NL80211_BAND_ATTR_IFTYPE_DATA,
   NL80211_BAND_ATTR_EDMG_CHANNELS,
   NL80211_BAND_ATTR_EDMG_BW_CONFIG,
+  NL80211_BAND_ATTR_S1G_MCS_NSS_SET,
+  NL80211_BAND_ATTR_S1G_CAPA,
   __NL80211_BAND_ATTR_AFTER_LAST,
   NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
 };
@@ -1537,6 +1543,7 @@
   NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE,
   NL80211_EXT_FEATURE_PUNCT,
   NL80211_EXT_FEATURE_SECURE_NAN,
+  NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
   NUM_NL80211_EXT_FEATURES,
   MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
 };
diff --git a/libc/kernel/uapi/linux/parport.h b/libc/kernel/uapi/linux/parport.h
index 8152224..611775f 100644
--- a/libc/kernel/uapi/linux/parport.h
+++ b/libc/kernel/uapi/linux/parport.h
@@ -75,4 +75,7 @@
 #define IEEE1284_DATA 0
 #define PARPORT_EPP_FAST (1 << 0)
 #define PARPORT_W91284PIC (1 << 1)
+#define PARPORT_EPP_FAST_32 PARPORT_EPP_FAST
+#define PARPORT_EPP_FAST_16 (1 << 2)
+#define PARPORT_EPP_FAST_8 (1 << 3)
 #endif
diff --git a/libc/kernel/uapi/linux/pkt_sched.h b/libc/kernel/uapi/linux/pkt_sched.h
index c31b8bb..8d561a4 100644
--- a/libc/kernel/uapi/linux/pkt_sched.h
+++ b/libc/kernel/uapi/linux/pkt_sched.h
@@ -532,6 +532,10 @@
   __TC_MQPRIO_SHAPER_MAX
 };
 #define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)
+enum {
+  TC_FP_EXPRESS = 1,
+  TC_FP_PREEMPTIBLE = 2,
+};
 struct tc_mqprio_qopt {
   __u8 num_tc;
   __u8 prio_tc_map[TC_QOPT_BITMASK + 1];
@@ -544,11 +548,19 @@
 #define TC_MQPRIO_F_MIN_RATE 0x4
 #define TC_MQPRIO_F_MAX_RATE 0x8
 enum {
+  TCA_MQPRIO_TC_ENTRY_UNSPEC,
+  TCA_MQPRIO_TC_ENTRY_INDEX,
+  TCA_MQPRIO_TC_ENTRY_FP,
+  __TCA_MQPRIO_TC_ENTRY_CNT,
+  TCA_MQPRIO_TC_ENTRY_MAX = (__TCA_MQPRIO_TC_ENTRY_CNT - 1)
+};
+enum {
   TCA_MQPRIO_UNSPEC,
   TCA_MQPRIO_MODE,
   TCA_MQPRIO_SHAPER,
   TCA_MQPRIO_MIN_RATE64,
   TCA_MQPRIO_MAX_RATE64,
+  TCA_MQPRIO_TC_ENTRY,
   __TCA_MQPRIO_MAX,
 };
 #define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)
@@ -927,6 +939,7 @@
   TCA_TAPRIO_TC_ENTRY_UNSPEC,
   TCA_TAPRIO_TC_ENTRY_INDEX,
   TCA_TAPRIO_TC_ENTRY_MAX_SDU,
+  TCA_TAPRIO_TC_ENTRY_FP,
   __TCA_TAPRIO_TC_ENTRY_CNT,
   TCA_TAPRIO_TC_ENTRY_MAX = (__TCA_TAPRIO_TC_ENTRY_CNT - 1)
 };
diff --git a/libc/kernel/uapi/linux/pktcdvd.h b/libc/kernel/uapi/linux/pktcdvd.h
index eed22f8..c2414d1 100644
--- a/libc/kernel/uapi/linux/pktcdvd.h
+++ b/libc/kernel/uapi/linux/pktcdvd.h
@@ -23,7 +23,6 @@
 #define MAX_WRITERS 8
 #define PKT_RB_POOL_SIZE 512
 #define PACKET_WAIT_TIME (HZ * 5 / 1000)
-#define USE_WCACHING 0
 #define PACKET_CDR 1
 #define PACKET_CDRW 2
 #define PACKET_DVDR 3
diff --git a/libc/kernel/uapi/linux/prctl.h b/libc/kernel/uapi/linux/prctl.h
index 6ad1c04..ccab000 100644
--- a/libc/kernel/uapi/linux/prctl.h
+++ b/libc/kernel/uapi/linux/prctl.h
@@ -189,4 +189,7 @@
 #define PR_GET_MDWE 66
 #define PR_SET_VMA 0x53564d41
 #define PR_SET_VMA_ANON_NAME 0
+#define PR_GET_AUXV 0x41555856
+#define PR_SET_MEMORY_MERGE 67
+#define PR_GET_MEMORY_MERGE 68
 #endif
diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h
index 8c9ec80..5aefc1c 100644
--- a/libc/kernel/uapi/linux/psp-sev.h
+++ b/libc/kernel/uapi/linux/psp-sev.h
@@ -32,6 +32,7 @@
   SEV_MAX,
 };
 typedef enum {
+  SEV_RET_NO_FW_CALL = - 1,
   SEV_RET_SUCCESS = 0,
   SEV_RET_INVALID_PLATFORM_STATE,
   SEV_RET_INVALID_GUEST_STATE,
diff --git a/libc/kernel/uapi/linux/ptrace.h b/libc/kernel/uapi/linux/ptrace.h
index 4bfa59a..56a350b 100644
--- a/libc/kernel/uapi/linux/ptrace.h
+++ b/libc/kernel/uapi/linux/ptrace.h
@@ -90,6 +90,14 @@
   __u32 flags;
   __u32 pad;
 };
+#define PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG 0x4210
+#define PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG 0x4211
+struct ptrace_sud_config {
+  __u64 mode;
+  __u64 selector;
+  __u64 offset;
+  __u64 len;
+};
 #define PTRACE_EVENTMSG_SYSCALL_ENTRY 1
 #define PTRACE_EVENTMSG_SYSCALL_EXIT 2
 #define PTRACE_PEEKSIGINFO_SHARED (1 << 0)
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index 4bf2412..b1a571c 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -709,7 +709,9 @@
   SCTP_SS_DEFAULT = SCTP_SS_FCFS,
   SCTP_SS_PRIO,
   SCTP_SS_RR,
-  SCTP_SS_MAX = SCTP_SS_RR
+  SCTP_SS_FC,
+  SCTP_SS_WFQ,
+  SCTP_SS_MAX = SCTP_SS_WFQ
 };
 struct sctp_probeinterval {
   sctp_assoc_t spi_assoc_id;
diff --git a/libc/kernel/uapi/linux/sed-opal.h b/libc/kernel/uapi/linux/sed-opal.h
index 4685bb3..fa1d7ed 100644
--- a/libc/kernel/uapi/linux/sed-opal.h
+++ b/libc/kernel/uapi/linux/sed-opal.h
@@ -74,6 +74,15 @@
   __u32 WLE;
   struct opal_session_info session;
 };
+struct opal_lr_status {
+  struct opal_session_info session;
+  __u64 range_start;
+  __u64 range_length;
+  __u32 RLE;
+  __u32 WLE;
+  __u32 l_state;
+  __u8 align[4];
+};
 struct opal_lock_unlock {
   struct opal_session_info session;
   __u32 l_state;
@@ -127,6 +136,13 @@
   __u32 flags;
   __u32 reserved;
 };
+struct opal_geometry {
+  __u8 align;
+  __u32 logical_block_size;
+  __u64 alignment_granularity;
+  __u64 lowest_aligned_lba;
+  __u8 __align[3];
+};
 #define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock)
 #define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock)
 #define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key)
@@ -144,4 +160,6 @@
 #define IOC_OPAL_WRITE_SHADOW_MBR _IOW('p', 234, struct opal_shadow_mbr)
 #define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table)
 #define IOC_OPAL_GET_STATUS _IOR('p', 236, struct opal_status)
+#define IOC_OPAL_GET_LR_STATUS _IOW('p', 237, struct opal_lr_status)
+#define IOC_OPAL_GET_GEOMETRY _IOR('p', 238, struct opal_geometry)
 #endif
diff --git a/libc/kernel/uapi/linux/sev-guest.h b/libc/kernel/uapi/linux/sev-guest.h
index 796479a..3e8c0bf 100644
--- a/libc/kernel/uapi/linux/sev-guest.h
+++ b/libc/kernel/uapi/linux/sev-guest.h
@@ -42,7 +42,13 @@
   __u8 msg_version;
   __u64 req_data;
   __u64 resp_data;
-  __u64 fw_err;
+  union {
+    __u64 exitinfo2;
+    struct {
+      __u32 fw_error;
+      __u32 vmm_error;
+    };
+  };
 };
 struct snp_ext_report_req {
   struct snp_report_req data;
@@ -53,4 +59,9 @@
 #define SNP_GET_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x0, struct snp_guest_request_ioctl)
 #define SNP_GET_DERIVED_KEY _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x1, struct snp_guest_request_ioctl)
 #define SNP_GET_EXT_REPORT _IOWR(SNP_GUEST_REQ_IOC_TYPE, 0x2, struct snp_guest_request_ioctl)
+#define SNP_GUEST_FW_ERR_MASK GENMASK_ULL(31, 0)
+#define SNP_GUEST_VMM_ERR_SHIFT 32
+#define SNP_GUEST_VMM_ERR(x) (((u64) x) << SNP_GUEST_VMM_ERR_SHIFT)
+#define SNP_GUEST_VMM_ERR_INVALID_LEN 1
+#define SNP_GUEST_VMM_ERR_BUSY 2
 #endif
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 83e155e..84af2d2 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -61,7 +61,7 @@
       __u64 cdb_off;
       __u64 __pad1;
       __u64 __pad2;
-      struct iovec iov[0];
+      __DECLARE_FLEX_ARRAY(struct iovec, iov);
     } req;
     struct {
       __u8 scsi_status;
diff --git a/libc/kernel/uapi/linux/taskstats.h b/libc/kernel/uapi/linux/taskstats.h
index c1cda52..4f1637e 100644
--- a/libc/kernel/uapi/linux/taskstats.h
+++ b/libc/kernel/uapi/linux/taskstats.h
@@ -19,7 +19,7 @@
 #ifndef _LINUX_TASKSTATS_H
 #define _LINUX_TASKSTATS_H
 #include <linux/types.h>
-#define TASKSTATS_VERSION 13
+#define TASKSTATS_VERSION 14
 #define TS_COMM_LEN 32
 struct taskstats {
   __u16 version;
@@ -77,6 +77,8 @@
   __u64 ac_exe_inode;
   __u64 wpcopy_count;
   __u64 wpcopy_delay_total;
+  __u64 irq_count;
+  __u64 irq_delay_total;
 };
 enum {
   TASKSTATS_CMD_UNSPEC = 0,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
index e137ae8..7eb61e8 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
@@ -40,6 +40,7 @@
   TCA_TUNNEL_KEY_ENC_OPTS,
   TCA_TUNNEL_KEY_ENC_TOS,
   TCA_TUNNEL_KEY_ENC_TTL,
+  TCA_TUNNEL_KEY_NO_FRAG,
   __TCA_TUNNEL_KEY_MAX,
 };
 #define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
index 6e0a9f8..2d4f422 100644
--- a/libc/kernel/uapi/linux/ublk_cmd.h
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -30,9 +30,23 @@
 #define UBLK_CMD_START_USER_RECOVERY 0x10
 #define UBLK_CMD_END_USER_RECOVERY 0x11
 #define UBLK_CMD_GET_DEV_INFO2 0x12
+#define UBLK_U_CMD_GET_QUEUE_AFFINITY _IOR('u', UBLK_CMD_GET_QUEUE_AFFINITY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_DEV_INFO _IOR('u', UBLK_CMD_GET_DEV_INFO, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_ADD_DEV _IOWR('u', UBLK_CMD_ADD_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_DEL_DEV _IOWR('u', UBLK_CMD_DEL_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_START_DEV _IOWR('u', UBLK_CMD_START_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_STOP_DEV _IOWR('u', UBLK_CMD_STOP_DEV, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_SET_PARAMS _IOWR('u', UBLK_CMD_SET_PARAMS, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_PARAMS _IOR('u', UBLK_CMD_GET_PARAMS, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_START_USER_RECOVERY _IOWR('u', UBLK_CMD_START_USER_RECOVERY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_END_USER_RECOVERY _IOWR('u', UBLK_CMD_END_USER_RECOVERY, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_GET_DEV_INFO2 _IOR('u', UBLK_CMD_GET_DEV_INFO2, struct ublksrv_ctrl_cmd)
 #define UBLK_IO_FETCH_REQ 0x20
 #define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
 #define UBLK_IO_NEED_GET_DATA 0x22
+#define UBLK_U_IO_FETCH_REQ _IOWR('u', UBLK_IO_FETCH_REQ, struct ublksrv_io_cmd)
+#define UBLK_U_IO_COMMIT_AND_FETCH_REQ _IOWR('u', UBLK_IO_COMMIT_AND_FETCH_REQ, struct ublksrv_io_cmd)
+#define UBLK_U_IO_NEED_GET_DATA _IOWR('u', UBLK_IO_NEED_GET_DATA, struct ublksrv_io_cmd)
 #define UBLK_IO_RES_OK 0
 #define UBLK_IO_RES_NEED_GET_DATA 1
 #define UBLK_IO_RES_ABORT (- ENODEV)
@@ -45,6 +59,7 @@
 #define UBLK_F_USER_RECOVERY (1UL << 3)
 #define UBLK_F_USER_RECOVERY_REISSUE (1UL << 4)
 #define UBLK_F_UNPRIVILEGED_DEV (1UL << 5)
+#define UBLK_F_CMD_IOCTL_ENCODE (1UL << 6)
 #define UBLK_S_DEV_DEAD 0
 #define UBLK_S_DEV_LIVE 1
 #define UBLK_S_DEV_QUIESCED 2
diff --git a/libc/kernel/uapi/linux/user_events.h b/libc/kernel/uapi/linux/user_events.h
new file mode 100644
index 0000000..f26519e
--- /dev/null
+++ b/libc/kernel/uapi/linux/user_events.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USER_EVENTS_H
+#define _UAPI_LINUX_USER_EVENTS_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#define USER_EVENTS_SYSTEM "user_events"
+#define USER_EVENTS_PREFIX "u:"
+#define DYN_LOC(offset,size) ((size) << 16 | (offset))
+struct user_reg {
+  __u32 size;
+  __u8 enable_bit;
+  __u8 enable_size;
+  __u16 flags;
+  __u64 enable_addr;
+  __u64 name_args;
+  __u32 write_index;
+} __attribute__((__packed__));
+struct user_unreg {
+  __u32 size;
+  __u8 disable_bit;
+  __u8 __reserved;
+  __u16 __reserved2;
+  __u64 disable_addr;
+} __attribute__((__packed__));
+#define DIAG_IOC_MAGIC '*'
+#define DIAG_IOCSREG _IOWR(DIAG_IOC_MAGIC, 0, struct user_reg *)
+#define DIAG_IOCSDEL _IOW(DIAG_IOC_MAGIC, 1, char *)
+#define DIAG_IOCSUNREG _IOW(DIAG_IOC_MAGIC, 2, struct user_unreg *)
+#endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index 09e0d80..816198f 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -23,7 +23,7 @@
 #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)
+#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)
 #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)
 #define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY | (__u64) 1 << _UFFDIO_CONTINUE | (__u64) 1 << _UFFDIO_WRITEPROTECT)
@@ -99,6 +99,7 @@
 #define UFFD_FEATURE_MINOR_SHMEM (1 << 10)
 #define UFFD_FEATURE_EXACT_ADDRESS (1 << 11)
 #define UFFD_FEATURE_WP_HUGETLBFS_SHMEM (1 << 12)
+#define UFFD_FEATURE_WP_UNPOPULATED (1 << 13)
   __u64 features;
   __u64 ioctls;
 };
@@ -138,6 +139,7 @@
 struct uffdio_continue {
   struct uffdio_range range;
 #define UFFDIO_CONTINUE_MODE_DONTWAKE ((__u64) 1 << 0)
+#define UFFDIO_CONTINUE_MODE_WP ((__u64) 1 << 1)
   __u64 mode;
   __s64 mapped;
 };
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index 1505137..73529c9 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -16,14 +16,4 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#ifndef _UAPI_LINUX_UUID_H_
-#define _UAPI_LINUX_UUID_H_
-#include <linux/types.h>
-typedef struct {
-  __u8 b[16];
-} uuid_le;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_le) \
-{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-#endif
+#include <linux/mei_uuid.h>
diff --git a/libc/kernel/uapi/linux/v4l2-subdev.h b/libc/kernel/uapi/linux/v4l2-subdev.h
index 8b2c1bd..55d7192 100644
--- a/libc/kernel/uapi/linux/v4l2-subdev.h
+++ b/libc/kernel/uapi/linux/v4l2-subdev.h
@@ -115,6 +115,10 @@
   __u64 routes;
   __u32 reserved[6];
 };
+#define V4L2_SUBDEV_CLIENT_CAP_STREAMS (1U << 0)
+struct v4l2_subdev_client_capability {
+  __u64 capabilities;
+};
 #define v4l2_subdev_edid v4l2_edid
 #define VIDIOC_SUBDEV_QUERYCAP _IOR('V', 0, struct v4l2_subdev_capability)
 #define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
@@ -130,6 +134,8 @@
 #define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection)
 #define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing)
 #define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing)
+#define VIDIOC_SUBDEV_G_CLIENT_CAP _IOR('V', 101, struct v4l2_subdev_client_capability)
+#define VIDIOC_SUBDEV_S_CLIENT_CAP _IOWR('V', 102, struct v4l2_subdev_client_capability)
 #define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id)
 #define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id)
 #define VIDIOC_SUBDEV_ENUMSTD _IOWR('V', 25, struct v4l2_standard)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 9d48e3d..59df932 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,8 +16,8 @@
  ***
  ****************************************************************************
  ****************************************************************************/
-#define LINUX_VERSION_CODE 393984
+#define LINUX_VERSION_CODE 394240
 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
 #define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 3
+#define LINUX_VERSION_PATCHLEVEL 4
 #define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 95c2d94..b762feb 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -247,11 +247,14 @@
 #define V4L2_PIX_FMT_RGBX1010102 v4l2_fourcc('R', 'X', '3', '0')
 #define V4L2_PIX_FMT_RGBA1010102 v4l2_fourcc('R', 'A', '3', '0')
 #define V4L2_PIX_FMT_ARGB2101010 v4l2_fourcc('A', 'R', '3', '0')
+#define V4L2_PIX_FMT_BGR48_12 v4l2_fourcc('B', '3', '1', '2')
+#define V4L2_PIX_FMT_ABGR64_12 v4l2_fourcc('B', '4', '1', '2')
 #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y')
 #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ')
 #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ')
 #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ')
 #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ')
+#define V4L2_PIX_FMT_Y012 v4l2_fourcc('Y', '0', '1', '2')
 #define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ')
 #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
 #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
@@ -278,6 +281,7 @@
 #define V4L2_PIX_FMT_YUVA32 v4l2_fourcc('Y', 'U', 'V', 'A')
 #define V4L2_PIX_FMT_YUVX32 v4l2_fourcc('Y', 'U', 'V', 'X')
 #define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0')
+#define V4L2_PIX_FMT_YUV48_12 v4l2_fourcc('Y', '3', '1', '2')
 #define V4L2_PIX_FMT_Y210 v4l2_fourcc('Y', '2', '1', '0')
 #define V4L2_PIX_FMT_Y212 v4l2_fourcc('Y', '2', '1', '2')
 #define V4L2_PIX_FMT_Y216 v4l2_fourcc('Y', '2', '1', '6')
@@ -288,10 +292,12 @@
 #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4')
 #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2')
 #define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0')
+#define V4L2_PIX_FMT_P012 v4l2_fourcc('P', '0', '1', '2')
 #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2')
 #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1')
 #define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6')
 #define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1')
+#define V4L2_PIX_FMT_P012M v4l2_fourcc('P', 'M', '1', '2')
 #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9')
 #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9')
 #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P')
@@ -380,6 +386,9 @@
 #define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H')
 #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4')
 #define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5')
+#define V4L2_PIX_FMT_SPK v4l2_fourcc('S', 'P', 'K', '0')
+#define V4L2_PIX_FMT_RV30 v4l2_fourcc('R', 'V', '3', '0')
+#define V4L2_PIX_FMT_RV40 v4l2_fourcc('R', 'V', '4', '0')
 #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A')
 #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A')
 #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0')
diff --git a/libc/kernel/uapi/linux/virtio_config.h b/libc/kernel/uapi/linux/virtio_config.h
index bdd2e73..152d854 100644
--- a/libc/kernel/uapi/linux/virtio_config.h
+++ b/libc/kernel/uapi/linux/virtio_config.h
@@ -38,5 +38,6 @@
 #define VIRTIO_F_IN_ORDER 35
 #define VIRTIO_F_ORDER_PLATFORM 36
 #define VIRTIO_F_SR_IOV 37
+#define VIRTIO_F_NOTIFICATION_DATA 38
 #define VIRTIO_F_RING_RESET 40
 #endif
diff --git a/libc/kernel/uapi/linux/virtio_net.h b/libc/kernel/uapi/linux/virtio_net.h
index da7285e..d2554a0 100644
--- a/libc/kernel/uapi/linux/virtio_net.h
+++ b/libc/kernel/uapi/linux/virtio_net.h
@@ -50,6 +50,7 @@
 #define VIRTIO_NET_F_GUEST_USO6 55
 #define VIRTIO_NET_F_HOST_USO 56
 #define VIRTIO_NET_F_HASH_REPORT 57
+#define VIRTIO_NET_F_GUEST_HDRLEN 59
 #define VIRTIO_NET_F_RSS 60
 #define VIRTIO_NET_F_RSC_EXT 61
 #define VIRTIO_NET_F_STANDBY 62
diff --git a/libc/kernel/uapi/rdma/bnxt_re-abi.h b/libc/kernel/uapi/rdma/bnxt_re-abi.h
index 62ba685..cab6aa4 100644
--- a/libc/kernel/uapi/rdma/bnxt_re-abi.h
+++ b/libc/kernel/uapi/rdma/bnxt_re-abi.h
@@ -60,6 +60,9 @@
   __u32 phase;
   __u32 rsvd;
 };
+struct bnxt_re_resize_cq_req {
+  __aligned_u64 cq_va;
+};
 struct bnxt_re_qp_req {
   __aligned_u64 qpsva;
   __aligned_u64 qprva;
diff --git a/libc/kernel/uapi/rdma/efa-abi.h b/libc/kernel/uapi/rdma/efa-abi.h
index bfb3f18..aab5902 100644
--- a/libc/kernel/uapi/rdma/efa-abi.h
+++ b/libc/kernel/uapi/rdma/efa-abi.h
@@ -104,6 +104,8 @@
   EFA_QUERY_DEVICE_CAPS_RNR_RETRY = 1 << 1,
   EFA_QUERY_DEVICE_CAPS_CQ_NOTIFICATIONS = 1 << 2,
   EFA_QUERY_DEVICE_CAPS_CQ_WITH_SGID = 1 << 3,
+  EFA_QUERY_DEVICE_CAPS_DATA_POLLING_128 = 1 << 4,
+  EFA_QUERY_DEVICE_CAPS_RDMA_WRITE = 1 << 5,
 };
 struct efa_ibv_ex_query_device_resp {
   __u32 comp_mask;
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index 1940e5d..b156267 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -149,9 +149,9 @@
   __le32 type;
   __le32 num_elems;
   union {
-    struct snd_soc_tplg_vendor_uuid_elem uuid[0];
-    struct snd_soc_tplg_vendor_value_elem value[0];
-    struct snd_soc_tplg_vendor_string_elem string[0];
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_uuid_elem, uuid);
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_value_elem, value);
+    __DECLARE_FLEX_ARRAY(struct snd_soc_tplg_vendor_string_elem, string);
   };
 } __attribute__((packed));
 struct snd_soc_tplg_private {
diff --git a/libc/kernel/uapi/sound/emu10k1.h b/libc/kernel/uapi/sound/emu10k1.h
index 483309e..5ecdf71 100644
--- a/libc/kernel/uapi/sound/emu10k1.h
+++ b/libc/kernel/uapi/sound/emu10k1.h
@@ -21,8 +21,6 @@
 #ifdef __linux__
 #include <linux/types.h>
 #endif
-#define EMU10K1_CARD_CREATIVE 0x00000000
-#define EMU10K1_CARD_EMUAPS 0x00000001
 #define EMU10K1_FX8010_PCM_COUNT 8
 #define __EMU10K1_DECLARE_BITMAP(name,bits) unsigned long name[(bits) / (sizeof(unsigned long) * 8)]
 #define iMAC0 0x00
@@ -41,10 +39,29 @@
 #define iEXP 0x0d
 #define iINTERP 0x0e
 #define iSKIP 0x0f
+#define LOWORD_OPX_MASK 0x000ffc00
+#define LOWORD_OPY_MASK 0x000003ff
+#define HIWORD_OPCODE_MASK 0x00f00000
+#define HIWORD_RESULT_MASK 0x000ffc00
+#define HIWORD_OPA_MASK 0x000003ff
+#define A_LOWORD_OPX_MASK 0x007ff000
+#define A_LOWORD_OPY_MASK 0x000007ff
+#define A_HIWORD_OPCODE_MASK 0x0f000000
+#define A_HIWORD_RESULT_MASK 0x007ff000
+#define A_HIWORD_OPA_MASK 0x000007ff
 #define FXBUS(x) (0x00 + (x))
 #define EXTIN(x) (0x10 + (x))
 #define EXTOUT(x) (0x20 + (x))
 #define FXBUS2(x) (0x30 + (x))
+#define A_FXBUS(x) (0x00 + (x))
+#define A_EXTIN(x) (0x40 + (x))
+#define A_P16VIN(x) (0x50 + (x))
+#define A_EXTOUT(x) (0x60 + (x))
+#define A_FXBUS2(x) (0x80 + (x))
+#define A_EMU32OUTH(x) (0xa0 + (x))
+#define A_EMU32OUTL(x) (0xb0 + (x))
+#define A3_EMU32IN(x) (0x160 + (x))
+#define A3_EMU32OUT(x) (0x1E0 + (x))
 #define C_00000000 0x40
 #define C_00000001 0x41
 #define C_00000002 0x42
@@ -73,33 +90,71 @@
 #define GPR_NOISE1 0x59
 #define GPR_IRQ 0x5a
 #define GPR_DBAC 0x5b
+#define A_C_00000000 0xc0
+#define A_C_00000001 0xc1
+#define A_C_00000002 0xc2
+#define A_C_00000003 0xc3
+#define A_C_00000004 0xc4
+#define A_C_00000008 0xc5
+#define A_C_00000010 0xc6
+#define A_C_00000020 0xc7
+#define A_C_00000100 0xc8
+#define A_C_00010000 0xc9
+#define A_C_00000800 0xca
+#define A_C_10000000 0xcb
+#define A_C_20000000 0xcc
+#define A_C_40000000 0xcd
+#define A_C_80000000 0xce
+#define A_C_7fffffff 0xcf
+#define A_C_ffffffff 0xd0
+#define A_C_fffffffe 0xd1
+#define A_C_c0000000 0xd2
+#define A_C_4f1bbcdc 0xd3
+#define A_C_5a7ef9db 0xd4
+#define A_C_00100000 0xd5
+#define A_GPR_ACCU 0xd6
+#define A_GPR_COND 0xd7
+#define A_GPR_NOISE0 0xd8
+#define A_GPR_NOISE1 0xd9
+#define A_GPR_IRQ 0xda
+#define A_GPR_DBAC 0xdb
+#define A_GPR_DBACE 0xde
+#define FXGPREGBASE 0x100
+#define A_FXGPREGBASE 0x400
+#define A_TANKMEMCTLREGBASE 0x100
+#define A_TANKMEMCTLREG_MASK 0x1f
+#define TANKMEMDATAREGBASE 0x200
+#define TANKMEMDATAREG_MASK 0x000fffff
+#define TANKMEMADDRREGBASE 0x300
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff
+#define TANKMEMADDRREG_CLEAR 0x00800000
+#define TANKMEMADDRREG_ALIGN 0x00400000
+#define TANKMEMADDRREG_WRITE 0x00200000
+#define TANKMEMADDRREG_READ 0x00100000
 #define GPR(x) (FXGPREGBASE + (x))
 #define ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
 #define ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0x80 + (x))
 #define ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
 #define ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x80 + (x))
+#define A_GPR(x) (A_FXGPREGBASE + (x))
 #define A_ITRAM_DATA(x) (TANKMEMDATAREGBASE + 0x00 + (x))
 #define A_ETRAM_DATA(x) (TANKMEMDATAREGBASE + 0xc0 + (x))
 #define A_ITRAM_ADDR(x) (TANKMEMADDRREGBASE + 0x00 + (x))
 #define A_ETRAM_ADDR(x) (TANKMEMADDRREGBASE + 0xc0 + (x))
 #define A_ITRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0x00 + (x))
 #define A_ETRAM_CTL(x) (A_TANKMEMCTLREGBASE + 0xc0 + (x))
-#define A_FXBUS(x) (0x00 + (x))
-#define A_EXTIN(x) (0x40 + (x))
-#define A_P16VIN(x) (0x50 + (x))
-#define A_EXTOUT(x) (0x60 + (x))
-#define A_FXBUS2(x) (0x80 + (x))
-#define A_EMU32OUTH(x) (0xa0 + (x))
-#define A_EMU32OUTL(x) (0xb0 + (x))
-#define A3_EMU32IN(x) (0x160 + (x))
-#define A3_EMU32OUT(x) (0x1E0 + (x))
-#define A_GPR(x) (A_FXGPREGBASE + (x))
 #define CC_REG_NORMALIZED C_00000001
 #define CC_REG_BORROW C_00000002
 #define CC_REG_MINUS C_00000004
 #define CC_REG_ZERO C_00000008
 #define CC_REG_SATURATE C_00000010
 #define CC_REG_NONZERO C_00000100
+#define A_CC_REG_NORMALIZED A_C_00000001
+#define A_CC_REG_BORROW A_C_00000002
+#define A_CC_REG_MINUS A_C_00000004
+#define A_CC_REG_ZERO A_C_00000008
+#define A_CC_REG_SATURATE A_C_00000010
+#define A_CC_REG_NONZERO A_C_00000100
 #define FXBUS_PCM_LEFT 0x00
 #define FXBUS_PCM_RIGHT 0x01
 #define FXBUS_PCM_LEFT_REAR 0x02
@@ -180,35 +235,6 @@
 #define A_EXTOUT_ADC_CAP_L 0x16
 #define A_EXTOUT_ADC_CAP_R 0x17
 #define A_EXTOUT_MIC_CAP 0x18
-#define A_C_00000000 0xc0
-#define A_C_00000001 0xc1
-#define A_C_00000002 0xc2
-#define A_C_00000003 0xc3
-#define A_C_00000004 0xc4
-#define A_C_00000008 0xc5
-#define A_C_00000010 0xc6
-#define A_C_00000020 0xc7
-#define A_C_00000100 0xc8
-#define A_C_00010000 0xc9
-#define A_C_00000800 0xca
-#define A_C_10000000 0xcb
-#define A_C_20000000 0xcc
-#define A_C_40000000 0xcd
-#define A_C_80000000 0xce
-#define A_C_7fffffff 0xcf
-#define A_C_ffffffff 0xd0
-#define A_C_fffffffe 0xd1
-#define A_C_c0000000 0xd2
-#define A_C_4f1bbcdc 0xd3
-#define A_C_5a7ef9db 0xd4
-#define A_C_00100000 0xd5
-#define A_GPR_ACCU 0xd6
-#define A_GPR_COND 0xd7
-#define A_GPR_NOISE0 0xd8
-#define A_GPR_NOISE1 0xd9
-#define A_GPR_IRQ 0xda
-#define A_GPR_DBAC 0xdb
-#define A_GPR_DBACE 0xde
 #define EMU10K1_DBG_ZC 0x80000000
 #define EMU10K1_DBG_SATURATION_OCCURED 0x02000000
 #define EMU10K1_DBG_SATURATION_ADDR 0x01ff0000
@@ -216,11 +242,13 @@
 #define EMU10K1_DBG_STEP 0x00004000
 #define EMU10K1_DBG_CONDITION_CODE 0x00003e00
 #define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff
-#define TANKMEMADDRREG_ADDR_MASK 0x000fffff
-#define TANKMEMADDRREG_CLEAR 0x00800000
-#define TANKMEMADDRREG_ALIGN 0x00400000
-#define TANKMEMADDRREG_WRITE 0x00200000
-#define TANKMEMADDRREG_READ 0x00100000
+#define A_DBG_ZC 0x40000000
+#define A_DBG_SATURATION_OCCURED 0x20000000
+#define A_DBG_SATURATION_ADDR 0x0ffc0000
+#define A_DBG_SINGLE_STEP 0x00020000
+#define A_DBG_STEP 0x00010000
+#define A_DBG_CONDITION_CODE 0x0000f800
+#define A_DBG_STEP_ADDR 0x000003ff
 struct snd_emu10k1_fx8010_info {
   unsigned int internal_tram_size;
   unsigned int external_tram_size;
diff --git a/libc/kernel/uapi/sound/skl-tplg-interface.h b/libc/kernel/uapi/sound/skl-tplg-interface.h
index 6dd9655..ff3d42a 100644
--- a/libc/kernel/uapi/sound/skl-tplg-interface.h
+++ b/libc/kernel/uapi/sound/skl-tplg-interface.h
@@ -47,7 +47,8 @@
   SKL_CH_CFG_DUAL_MONO = 9,
   SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
   SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
-  SKL_CH_CFG_4_CHANNEL = 12,
+  SKL_CH_CFG_7_1 = 12,
+  SKL_CH_CFG_4_CHANNEL = SKL_CH_CFG_7_1,
   SKL_CH_CFG_INVALID
 };
 enum skl_module_type {
diff --git a/libc/kernel/uapi/sound/sof/abi.h b/libc/kernel/uapi/sound/sof/abi.h
index dc4e525..a4844d6 100644
--- a/libc/kernel/uapi/sound/sof/abi.h
+++ b/libc/kernel/uapi/sound/sof/abi.h
@@ -35,4 +35,5 @@
 #define SOF_ABI_VERSION_INCOMPATIBLE(sof_ver,client_ver) (SOF_ABI_VERSION_MAJOR((sof_ver)) != SOF_ABI_VERSION_MAJOR((client_ver)))
 #define SOF_ABI_VERSION SOF_ABI_VER(SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH)
 #define SOF_ABI_MAGIC 0x00464F53
+#define SOF_IPC4_ABI_MAGIC 0x34464F53
 #endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index 3726546..48ef360 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -39,6 +39,7 @@
 #define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
 #define SOF_TKN_SCHED_LP_MODE 207
 #define SOF_TKN_SCHED_MEM_USAGE 208
+#define SOF_TKN_SCHED_USE_CHAIN_DMA 209
 #define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
 #define SOF_TKN_VOLUME_RAMP_STEP_MS 251
 #define SOF_TKN_GAIN_RAMP_TYPE 260
@@ -59,10 +60,12 @@
 #define SOF_TKN_COMP_CPC 406
 #define SOF_TKN_COMP_IS_PAGES 409
 #define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410
-#define SOF_TKN_COMP_NUM_SINK_PINS 411
-#define SOF_TKN_COMP_NUM_SOURCE_PINS 412
-#define SOF_TKN_COMP_SINK_PIN_BINDING_WNAME 413
-#define SOF_TKN_COMP_SRC_PIN_BINDING_WNAME 414
+#define SOF_TKN_COMP_NUM_INPUT_PINS 411
+#define SOF_TKN_COMP_NUM_OUTPUT_PINS 412
+#define SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME 413
+#define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 414
+#define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415
+#define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416
 #define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
 #define SOF_TKN_INTEL_SSP_MCLK_ID 501
 #define SOF_TKN_INTEL_SSP_SAMPLE_BITS 502
@@ -107,26 +110,29 @@
 #define SOF_TKN_AMD_ACPDMIC_CH 1801
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901
-#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902
+#define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT_DEPTH 1902
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908
+#define SOF_TKN_CAVS_AUDIO_FORMAT_INPUT_PIN_INDEX 1909
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931
-#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT_DEPTH 1932
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE 1936
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG 1937
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_SAMPLE_TYPE 1938
+#define SOF_TKN_CAVS_AUDIO_FORMAT_OUTPUT_PIN_INDEX 1939
 #define SOF_TKN_CAVS_AUDIO_FORMAT_IBS 1970
 #define SOF_TKN_CAVS_AUDIO_FORMAT_OBS 1971
 #define SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE 1972
 #define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980
+#define SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS 1981
 #define SOF_TKN_AMD_ACPI2S_RATE 1700
 #define SOF_TKN_AMD_ACPI2S_CH 1701
 #define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index c69e609..e90618d 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -955,7 +955,7 @@
     sigaction;
     sigaddset; # introduced=21
     sigaltstack;
-    sigblock;
+    sigblock; # arm x86 arm64 x86_64
     sigdelset; # introduced=21
     sigemptyset; # introduced=21
     sigfillset; # introduced=21
@@ -968,7 +968,7 @@
     sigprocmask;
     sigqueue; # introduced=23
     sigsetjmp; # introduced-arm=9 introduced-arm64=21 introduced-x86=12 introduced-x86_64=21
-    sigsetmask;
+    sigsetmask; # arm x86 arm64 x86_64
     sigsuspend;
     sigtimedwait; # introduced=23
     sigwait;
@@ -1589,6 +1589,8 @@
     localtime_rz;
     mbsrtowcs_l;
     mktime_z;
+    __riscv_flush_icache; # riscv64
+    __riscv_hwprobe; # riscv64
     timespec_getres;
     tzalloc;
     tzfree;
diff --git a/libc/private/SigSetConverter.h b/libc/private/SigSetConverter.h
index 7d0b215..9e9df73 100644
--- a/libc/private/SigSetConverter.h
+++ b/libc/private/SigSetConverter.h
@@ -28,8 +28,45 @@
 
 #pragma once
 
-union SigSetConverter {
-  int bsd;
-  sigset_t sigset;
-  sigset64_t sigset64;
+// Android's 32-bit ABI shipped with a sigset_t too small to include any
+// of the realtime signals, so we have both sigset_t and sigset64_t. Many
+// new system calls only accept a sigset64_t, so this helps paper over
+// the difference at zero cost to LP64 in most cases after the optimizer
+// removes the unnecessary temporary `ptr`.
+struct SigSetConverter {
+ public:
+  SigSetConverter(const sigset_t* s) : SigSetConverter(const_cast<sigset_t*>(s)) {}
+
+  SigSetConverter(sigset_t* s) {
+#if defined(__LP64__)
+    // sigset_t == sigset64_t on LP64.
+    ptr = s;
+#else
+    sigset64 = {};
+    if (s != nullptr) {
+      original_ptr = s;
+      sigset = *s;
+      ptr = &sigset64;
+    } else {
+      ptr = nullptr;
+    }
+#endif
+  }
+
+  void copy_out() {
+#if defined(__LP64__)
+    // We used the original pointer directly, so no copy needed.
+#else
+    *original_ptr = sigset;
+#endif
+  }
+
+  sigset64_t* ptr;
+
+ private:
+  [[maybe_unused]] sigset_t* original_ptr;
+  union {
+    sigset_t sigset;
+    sigset64_t sigset64;
+  };
 };
diff --git a/libc/private/thread_private.h b/libc/private/thread_private.h
index 1f9eeb6..1a13690 100644
--- a/libc/private/thread_private.h
+++ b/libc/private/thread_private.h
@@ -29,7 +29,6 @@
 
 #define _ARC4_LOCK() _thread_arc4_lock()
 #define _ARC4_UNLOCK() _thread_arc4_unlock()
-#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
 
 extern volatile sig_atomic_t _rs_forked;
 
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index 4f33777..8c457c8 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -227,11 +227,6 @@
     aliases = syscall["aliases"]
     for alias in aliases:
         stub += "\nALIAS_SYMBOL(%s, %s)\n" % (alias, syscall["func"])
-
-    # Use hidden visibility on LP64 for any functions beginning with underscores.
-    if pointer_length == 64 and syscall["func"].startswith("__"):
-        stub += '.hidden ' + syscall["func"] + '\n'
-
     return stub
 
 
diff --git a/libc/upstream-freebsd/android/include/libc_private.h b/libc/upstream-freebsd/android/include/libc_private.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libc/upstream-freebsd/android/include/libc_private.h
diff --git a/libc/upstream-freebsd/lib/libc/gen/ldexp.c b/libc/upstream-freebsd/lib/libc/gen/ldexp.c
deleted file mode 100644
index 887f673..0000000
--- a/libc/upstream-freebsd/lib/libc/gen/ldexp.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* @(#)s_scalbn.c 5.1 93/09/24 */
-/* @(#)fdlibm.h 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <machine/endian.h>
-#include <math.h>
-
-/* Bit fiddling routines copied from msun/src/math_private.h,v 1.15 */
-
-#if BYTE_ORDER == BIG_ENDIAN
-
-typedef union
-{
-  double value;
-  struct
-  {
-    u_int32_t msw;
-    u_int32_t lsw;
-  } parts;
-} ieee_double_shape_type;
-
-#endif
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-typedef union
-{
-  double value;
-  struct
-  {
-    u_int32_t lsw;
-    u_int32_t msw;
-  } parts;
-} ieee_double_shape_type;
-
-#endif
-
-/* Get two 32 bit ints from a double.  */
-
-#define EXTRACT_WORDS(ix0,ix1,d)				\
-do {								\
-  ieee_double_shape_type ew_u;					\
-  ew_u.value = (d);						\
-  (ix0) = ew_u.parts.msw;					\
-  (ix1) = ew_u.parts.lsw;					\
-} while (0)
-
-/* Get the more significant 32 bit int from a double.  */
-
-#define GET_HIGH_WORD(i,d)					\
-do {								\
-  ieee_double_shape_type gh_u;					\
-  gh_u.value = (d);						\
-  (i) = gh_u.parts.msw;						\
-} while (0)
-
-/* Set the more significant 32 bits of a double from an int.  */
-
-#define SET_HIGH_WORD(d,v)					\
-do {								\
-  ieee_double_shape_type sh_u;					\
-  sh_u.value = (d);						\
-  sh_u.parts.msw = (v);						\
-  (d) = sh_u.value;						\
-} while (0)
-
-
-static const double
-two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
-twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
-huge   = 1.0e+300,
-tiny   = 1.0e-300;
-
-static double
-_copysign(double x, double y)
-{
-	u_int32_t hx,hy;
-	GET_HIGH_WORD(hx,x);
-	GET_HIGH_WORD(hy,y);
-	SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
-	return x;
-}
-
-double
-ldexp(double x, int n)
-{
-	int32_t k,hx,lx;
-	EXTRACT_WORDS(hx,lx,x);
-        k = (hx&0x7ff00000)>>20;		/* extract exponent */
-        if (k==0) {				/* 0 or subnormal x */
-            if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
-	    x *= two54;
-	    GET_HIGH_WORD(hx,x);
-	    k = ((hx&0x7ff00000)>>20) - 54;
-            if (n< -50000) return tiny*x; 	/*underflow*/
-	    }
-        if (k==0x7ff) return x+x;		/* NaN or Inf */
-        k = k+n;
-        if (k >  0x7fe) return huge*_copysign(huge,x); /* overflow  */
-        if (k > 0) 				/* normal result */
-	    {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
-        if (k <= -54) {
-            if (n > 50000) 	/* in case integer overflow in n+k */
-		return huge*_copysign(huge,x);	/*overflow*/
-	    else return tiny*_copysign(tiny,x); 	/*underflow*/
-	}
-        k += 54;				/* subnormal result */
-	SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
-        return x*twom54;
-}
diff --git a/libc/upstream-freebsd/lib/libc/locale/wcsftime.c b/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
index aabb632..4fe6ad5 100644
--- a/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
+++ b/libc/upstream-freebsd/lib/libc/locale/wcsftime.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
index 6a3067c..1f3548b 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/getopt_long.c
@@ -55,7 +55,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt_long.c 342757 2019-01-04 03:13:24Z kevans $");
+__FBSDID("$FreeBSD$");
 
 #include <err.h>
 #include <errno.h>
@@ -88,7 +88,7 @@
 #define	BADARG		((*options == ':') ? (int)':' : (int)'?')
 #define	INORDER 	(int)1
 
-#define	EMSG		""
+static char EMSG[] = "";
 
 #ifdef GNU_COMPATIBLE
 #define NO_PREFIX	(-1)
@@ -194,7 +194,7 @@
 {
 	char *current_argv, *has_equal;
 #ifdef GNU_COMPATIBLE
-	char *current_dash;
+	const char *current_dash;
 #endif
 	size_t current_argv_len;
 	int i, match, exact_match, second_partial_match;
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c b/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
index b175d34..c9a0847 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hcreate.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2015 Nuxi, https://nuxi.nl/
  *
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdbool.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
index 34db88e..83e322a 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hcreate_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hcreate_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdlib.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
index 76d8a42..890bd08 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hdestroy_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hdestroy_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <search.h>
 #include <stdlib.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h b/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
index a0542b5..649933d 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hsearch.h
@@ -22,7 +22,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libc/stdlib/hsearch.h 292767 2015-12-27 07:50:11Z ed $
+ * $FreeBSD$
  */
 
 #ifndef HSEARCH_H
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c b/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
index 9a859d3..2fb5991 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/hsearch_r.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/hsearch_r.c 292767 2015-12-27 07:50:11Z ed $");
+__FBSDID("$FreeBSD$");
 
 #include <errno.h>
 #include <limits.h>
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
index e0db4f3..0d65cd1 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/qsort.c
@@ -33,12 +33,20 @@
 static char sccsid[] = "@(#)qsort.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/stdlib/qsort.c 334928 2018-06-10 17:54:44Z kib $");
+__FBSDID("$FreeBSD$");
 
+#include <errno.h>
+#include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
+#include "libc_private.h"
 
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
+typedef int		 cmp_t(const void *, const void *, void *);
+#elif defined(I_AM_QSORT_R_COMPAT)
 typedef int		 cmp_t(void *, const void *, const void *);
+#elif defined(I_AM_QSORT_S)
+typedef int		 cmp_t(const void *, const void *, void *);
 #else
 typedef int		 cmp_t(const void *, const void *);
 #endif
@@ -65,15 +73,19 @@
 #define	vecswap(a, b, n)				\
 	if ((n) > 0) swapfunc(a, b, n)
 
-#ifdef I_AM_QSORT_R
+#if defined(I_AM_QSORT_R)
+#define	CMP(t, x, y) (cmp((x), (y), (t)))
+#elif defined(I_AM_QSORT_R_COMPAT)
 #define	CMP(t, x, y) (cmp((t), (x), (y)))
+#elif defined(I_AM_QSORT_S)
+#define	CMP(t, x, y) (cmp((x), (y), (t)))
 #else
 #define	CMP(t, x, y) (cmp((x), (y)))
 #endif
 
 static inline char *
 med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
-#ifndef I_AM_QSORT_R
+#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_R_COMPAT) && !defined(I_AM_QSORT_S)
 __unused
 #endif
 )
@@ -83,20 +95,28 @@
 	      :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
 }
 
-#ifdef I_AM_QSORT_R
-void
-qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
-#else
-#define	thunk NULL
-void
-qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+/*
+ * The actual qsort() implementation is static to avoid preemptible calls when
+ * recursing. Also give them different names for improved debugging.
+ */
+#if defined(I_AM_QSORT_R)
+#define local_qsort local_qsort_r
+#elif defined(I_AM_QSORT_R_COMPAT)
+#define local_qsort local_qsort_r_compat
+#elif defined(I_AM_QSORT_S)
+#define local_qsort local_qsort_s
 #endif
+static void
+local_qsort(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk)
 {
 	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
 	size_t d1, d2;
 	int cmp_result;
 	int swap_cnt;
 
+	/* if there are less than 2 elements, then sorting is not needed */
+	if (__predict_false(n < 2))
+		return;
 loop:
 	swap_cnt = 0;
 	if (n < 7) {
@@ -160,7 +180,12 @@
 	pn = (char *)a + n * es;
 	d1 = MIN(pa - (char *)a, pb - pa);
 	vecswap(a, pb - d1, d1);
-	d1 = MIN(pd - pc, pn - pd - es);
+	/*
+	 * Cast es to preserve signedness of right-hand side of MIN()
+	 * expression, to avoid sign ambiguity in the implied comparison.  es
+	 * is safely within [0, SSIZE_MAX].
+	 */
+	d1 = MIN(pd - pc, pn - pd - (ssize_t)es);
 	vecswap(pb, pn - d1, d1);
 
 	d1 = pb - pa;
@@ -168,11 +193,7 @@
 	if (d1 <= d2) {
 		/* Recurse on left partition, then iterate on right partition */
 		if (d1 > es) {
-#ifdef I_AM_QSORT_R
-			qsort_r(a, d1 / es, es, thunk, cmp);
-#else
-			qsort(a, d1 / es, es, cmp);
-#endif
+			local_qsort(a, d1 / es, es, cmp, thunk);
 		}
 		if (d2 > es) {
 			/* Iterate rather than recurse to save stack space */
@@ -184,11 +205,7 @@
 	} else {
 		/* Recurse on right partition, then iterate on left partition */
 		if (d2 > es) {
-#ifdef I_AM_QSORT_R
-			qsort_r(pn - d2, d2 / es, es, thunk, cmp);
-#else
-			qsort(pn - d2, d2 / es, es, cmp);
-#endif
+			local_qsort(pn - d2, d2 / es, es, cmp, thunk);
 		}
 		if (d1 > es) {
 			/* Iterate rather than recurse to save stack space */
@@ -198,3 +215,53 @@
 		}
 	}
 }
+
+#if defined(I_AM_QSORT_R)
+void
+(qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk)
+{
+	local_qsort_r(a, n, es, cmp, thunk);
+}
+#elif defined(I_AM_QSORT_R_COMPAT)
+void
+__qsort_r_compat(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
+{
+	local_qsort_r_compat(a, n, es, cmp, thunk);
+}
+#elif defined(I_AM_QSORT_S)
+errno_t
+qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk)
+{
+	if (n > RSIZE_MAX) {
+		__throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL);
+		return (EINVAL);
+	} else if (es > RSIZE_MAX) {
+		__throw_constraint_handler_s("qsort_s : es > RSIZE_MAX",
+		    EINVAL);
+		return (EINVAL);
+	} else if (n != 0) {
+		if (a == NULL) {
+			__throw_constraint_handler_s("qsort_s : a == NULL",
+			    EINVAL);
+			return (EINVAL);
+		} else if (cmp == NULL) {
+			__throw_constraint_handler_s("qsort_s : cmp == NULL",
+			    EINVAL);
+			return (EINVAL);
+		} else if (es <= 0) {
+			__throw_constraint_handler_s("qsort_s : es <= 0",
+			    EINVAL);
+			return (EINVAL);
+		}
+	}
+
+	local_qsort_s(a, n, es, cmp, thunk);
+	return (0);
+}
+#else
+void
+qsort(void *a, size_t n, size_t es, cmp_t *cmp)
+{
+	local_qsort(a, n, es, cmp, NULL);
+}
+#endif
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
index 9e4e79d..d486b1a 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Chisnall
  * All rights reserved.
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: head/lib/libc/stdlib/quick_exit.c 326193 2017-11-25 17:12:48Z pfg $
+ * $FreeBSD$
  */
 
 #include <sys/types.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcpcpy.c b/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
index e040dba..41b7c51 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcpcpy.c
@@ -35,7 +35,7 @@
 static char sccsid[] = "@(#)strcpy.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcpcpy.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcpncpy.c b/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
index 8bf6e87..ccc64cd 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcpncpy.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcpncpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c b/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
index 5bd468d..03a61f8 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscasecmp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscasecmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 #include <wctype.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscat.c b/libc/upstream-freebsd/lib/libc/string/wcscat.c
index 792f61e..777a576 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscat.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c)1999 Citrus Project,
  * All rights reserved.
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcschr.c b/libc/upstream-freebsd/lib/libc/string/wcschr.c
index ca740c0..a7f1de0 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcschr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcschr.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcschr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscmp.c b/libc/upstream-freebsd/lib/libc/string/wcscmp.c
index db01892..7205238 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscmp.c
@@ -39,7 +39,7 @@
 __RCSID("$NetBSD: wcscmp.c,v 1.3 2001/01/05 12:13:12 itojun Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscmp.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscpy.c b/libc/upstream-freebsd/lib/libc/string/wcscpy.c
index a639e74..b400fae 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscpy.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcscspn.c b/libc/upstream-freebsd/lib/libc/string/wcscspn.c
index 8a7682f..a0db715 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcscspn.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcscspn.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcscspn.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcscspn.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsdup.c b/libc/upstream-freebsd/lib/libc/string/wcsdup.c
index b97f766..327574b 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsdup.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsdup.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Tim J. Robbins.
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsdup.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <stdlib.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcslcat.c b/libc/upstream-freebsd/lib/libc/string/wcslcat.c
index 9706fa6..f954b73 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcslcat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcslcat.c
@@ -35,7 +35,7 @@
 __RCSID("$NetBSD: wcslcat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcslcat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcslen.c b/libc/upstream-freebsd/lib/libc/string/wcslen.c
index c596825..cfd3aa2 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcslen.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcslen.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcslen.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcslen.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c b/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
index a963444..39f58be 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncasecmp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncasecmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 #include <wctype.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncat.c b/libc/upstream-freebsd/lib/libc/string/wcsncat.c
index 0214af4..eb13fab 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncat.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncat.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcsncat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncat.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncmp.c b/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
index 77b709c..55c88f6 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncmp.c
@@ -36,7 +36,7 @@
 __RCSID("$NetBSD: wcsncmp.c,v 1.3 2001/01/05 12:13:13 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncmp.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsncpy.c b/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
index 4075ecc..f86e40f 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsncpy.c
@@ -38,7 +38,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsncpy.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsnlen.c b/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
index 271d341..15fd520 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsnlen.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsnlen.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcspbrk.c b/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
index 63efb01..0e9ccf6 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcspbrk.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcspbrk.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcspbrk.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsrchr.c b/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
index 97665ca..cc5e7f2 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsrchr.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2002 Tim J. Robbins
  * All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsrchr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsspn.c b/libc/upstream-freebsd/lib/libc/string/wcsspn.c
index b08a39e..2b08acb 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsspn.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsspn.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wcsspn.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsspn.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcsstr.c b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
index 4309025..74921fe 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcsstr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcsstr.c
@@ -38,7 +38,7 @@
 #endif /* LIBC_SCCS and not lint */
 #endif
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcsstr.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wcstok.c b/libc/upstream-freebsd/lib/libc/string/wcstok.c
index 8d62bf7..b4bdc86 100644
--- a/libc/upstream-freebsd/lib/libc/string/wcstok.c
+++ b/libc/upstream-freebsd/lib/libc/string/wcstok.c
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/lib/libc/string/wcstok.c 326025 2017-11-20 19:49:47Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemchr.c b/libc/upstream-freebsd/lib/libc/string/wmemchr.c
index 412a276..42ae286 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemchr.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemchr.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemchr.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemchr.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemcmp.c b/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
index c1e9f3c..f1b1b00 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemcmp.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemcmp.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemcmp.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemcpy.c b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
index e0d6c04..30956eb 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemcpy.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemcpy.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <string.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemmove.c b/libc/upstream-freebsd/lib/libc/string/wmemmove.c
index b84c2c0..5e8da9f 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemmove.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemmove.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemmove.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemmove.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <string.h>
 #include <wchar.h>
diff --git a/libc/upstream-freebsd/lib/libc/string/wmemset.c b/libc/upstream-freebsd/lib/libc/string/wmemset.c
index d4d6308..fcf40ef 100644
--- a/libc/upstream-freebsd/lib/libc/string/wmemset.c
+++ b/libc/upstream-freebsd/lib/libc/string/wmemset.c
@@ -34,7 +34,7 @@
 __RCSID("$NetBSD: wmemset.c,v 1.1 2000/12/23 23:14:37 itojun Exp $");
 #endif /* LIBC_SCCS and not lint */
 #endif
-__FBSDID("$FreeBSD: head/lib/libc/string/wmemset.c 326193 2017-11-25 17:12:48Z pfg $");
+__FBSDID("$FreeBSD$");
 
 #include <wchar.h>
 
diff --git a/libc/upstream-netbsd/lib/libc/regex/regcomp.c b/libc/upstream-netbsd/lib/libc/regex/regcomp.c
index 957f8ac..86321c1 100644
--- a/libc/upstream-netbsd/lib/libc/regex/regcomp.c
+++ b/libc/upstream-netbsd/lib/libc/regex/regcomp.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: regcomp.c,v 1.46 2021/03/11 15:00:29 christos Exp $	*/
+/*	$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-3-Clause
@@ -51,9 +51,7 @@
 static char sccsid[] = "@(#)regcomp.c	8.5 (Berkeley) 3/20/94";
 __FBSDID("$FreeBSD: head/lib/libc/regex/regcomp.c 368359 2020-12-05 03:18:48Z kevans $");
 #endif
-__RCSID("$NetBSD: regcomp.c,v 1.46 2021/03/11 15:00:29 christos Exp $");
-
-#define _OPENBSD_SOURCE
+__RCSID("$NetBSD: regcomp.c,v 1.47 2022/12/21 17:44:15 wiz Exp $");
 
 #ifndef LIBHACK
 #define REGEX_GNU_EXTENSIONS
diff --git a/libc/upstream-netbsd/android/include/rand48.h b/libc/upstream-netbsd/lib/libc/stdlib/rand48.h
similarity index 80%
rename from libc/upstream-netbsd/android/include/rand48.h
rename to libc/upstream-netbsd/lib/libc/stdlib/rand48.h
index 1279906..1ad8b0d 100644
--- a/libc/upstream-netbsd/android/include/rand48.h
+++ b/libc/upstream-netbsd/lib/libc/stdlib/rand48.h
@@ -18,10 +18,10 @@
 
 #include <stdlib.h>
 
-__LIBC_HIDDEN__ void		__dorand48(unsigned short[3]);
-__LIBC_HIDDEN__ unsigned short	__rand48_seed[3];
-__LIBC_HIDDEN__ unsigned short	__rand48_mult[3];
-__LIBC_HIDDEN__ unsigned short	__rand48_add;
+extern void		__dorand48(unsigned short[3]);
+extern unsigned short	__rand48_seed[3];
+extern unsigned short	__rand48_mult[3];
+extern unsigned short	__rand48_add;
 
 #define	RAND48_SEED_0	(0x330e)
 #define	RAND48_SEED_1	(0xabcd)
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
index 6ee5a5c..af0169f 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_memstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_memstream.c,v 1.8 2019/05/02 08:30:10 yasuoka Exp $	*/
+/*	$OpenBSD: open_memstream.c,v 1.10 2023/07/11 12:14:16 claudio Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -53,7 +53,6 @@
 		p = recallocarray(st->string, st->size, sz, 1);
 		if (!p)
 			return (-1);
-		bzero(p + st->size, sz - st->size);
 		*st->pbuf = st->string = p;
 		st->size = sz;
 	}
@@ -136,7 +135,6 @@
 		return (NULL);
 	}
 
-	*st->string = '\0';
 	st->pos = 0;
 	st->len = 0;
 	st->pbuf = pbuf;
diff --git a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
index aceef35..fca0b71 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/open_wmemstream.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: open_wmemstream.c,v 1.8 2015/09/12 16:23:14 guenther Exp $	*/
+/*	$OpenBSD: open_wmemstream.c,v 1.10 2023/07/11 12:14:16 claudio Exp $	*/
 
 /*
  * Copyright (c) 2011 Martin Pieuchot <mpi@openbsd.org>
@@ -52,10 +52,9 @@
 
 		if (sz < end + 1)
 			sz = end + 1;
-		p = reallocarray(st->string, sz, sizeof(wchar_t));
+		p = recallocarray(st->string, st->size, sz, sizeof(wchar_t));
 		if (!p)
 			return (-1);
-		bzero(p + st->size, (sz - st->size) * sizeof(wchar_t));
 		*st->pbuf = st->string = p;
 		st->size = sz;
 	}
@@ -146,7 +145,6 @@
 		return (NULL);
 	}
 
-	*st->string = L'\0';
 	st->pos = 0;
 	st->len = 0;
 	st->pbuf = pbuf;
diff --git a/libm/Android.bp b/libm/Android.bp
index 079fd9a..bfb7a8c 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -509,3 +509,8 @@
     tools: ["generate-version-script"],
     cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
 }
+
+filegroup {
+    name: "libc_ldexp_srcs",
+    srcs: ["upstream-freebsd/lib/msun/src/s_scalbn.c"],
+}
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
index ab93732..3ba767b 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
index 423b568..3f505c5 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/invtrig.h
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
index 159338f..3faf7a7 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
+++ b/libm/upstream-freebsd/lib/msun/ld128/k_expl.h
@@ -1,7 +1,7 @@
 /* from: FreeBSD: head/lib/msun/ld128/s_expl.c 251345 2013-06-03 20:09:22Z kargl */
 
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009-2013 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
index ee3d2c7..bcbdc5f 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_exp2l.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
index 5b786af..5fc4380 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_expl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2009-2013 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
index 4774a27..40a22c0 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_logl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007-2013 Bruce D. Evans
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
index 45d10e5..cde3f18 100644
--- a/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
+++ b/libm/upstream-freebsd/lib/msun/ld128/s_nanl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/catrig.c b/libm/upstream-freebsd/lib/msun/src/catrig.c
index 431d8e6..82061b5 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrig.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrig.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/catrigf.c b/libm/upstream-freebsd/lib/msun/src/catrigf.c
index 62bcd39..fb4a6bf 100644
--- a/libm/upstream-freebsd/lib/msun/src/catrigf.c
+++ b/libm/upstream-freebsd/lib/msun/src/catrigf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2012 Stephen Montgomery-Smith <stephen@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_jn.c b/libm/upstream-freebsd/lib/msun/src/e_jn.c
index c7ba7da..5aaebd4 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_jn.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_jn.c
@@ -22,15 +22,15 @@
  *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
  *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
  * Note 2. About jn(n,x), yn(n,x)
- *	For n=0, j0(x) is called,
- *	for n=1, j1(x) is called,
- *	for n<x, forward recursion us used starting
+ *	For n=0, j0(x) is called.
+ *	For n=1, j1(x) is called.
+ *	For n<x, forward recursion is used starting
  *	from values of j0(x) and j1(x).
- *	for n>x, a continued fraction approximation to
+ *	For n>x, a continued fraction approximation to
  *	j(n,x)/j(n-1,x) is evaluated and then backward
  *	recursion is used starting from a supposed value
- *	for j(n,x). The resulting value of j(0,x) is
- *	compared with the actual value to correct the
+ *	for j(n,x). The resulting values of j(0,x) or j(1,x) are
+ *	compared with the actual values to correct the
  *	supposed value of j(n,x).
  *
  *	yn(n,x) is similar in all respects, except
diff --git a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
index be70767..48da493 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_lgamma_r.c
@@ -27,7 +27,7 @@
  *			    = log(6.3*5.3) + lgamma(5.3)
  *			    = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
  *   2. Polynomial approximation of lgamma around its
- *	minimun ymin=1.461632144968362245 to maintain monotonicity.
+ *	minimum ymin=1.461632144968362245 to maintain monotonicity.
  *	On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
  *		Let z = x-ymin;
  *		lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
diff --git a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
index 4a67863..2295673 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_remainderl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
index 565d963..67c777f 100644
--- a/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/e_sqrtl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_exp.c b/libm/upstream-freebsd/lib/msun/src/k_exp.c
index dd15ff4..1b86cd6 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_exp.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_exp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_expf.c b/libm/upstream-freebsd/lib/msun/src/k_expf.c
index 80e629b..7071632 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_expf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_expf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/k_tanf.c b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
index 52f1aaa..5be1445 100644
--- a/libm/upstream-freebsd/lib/msun/src/k_tanf.c
+++ b/libm/upstream-freebsd/lib/msun/src/k_tanf.c
@@ -50,7 +50,7 @@
 	 * We add the small terms from lowest degree up for efficiency on
 	 * non-sequential machines (the lowest degree terms tend to be ready
 	 * earlier).  Apart from this, we don't care about order of
-	 * operations, and don't need to to care since we have precision to
+	 * operations, and don't need to care since we have precision to
 	 * spare.  However, the chosen splitting is good for accuracy too,
 	 * and would give results as accurate as Horner's method if the
 	 * small terms were added from highest degree down.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_carg.c b/libm/upstream-freebsd/lib/msun/src/s_carg.c
index 1611b9d..f203198 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_carg.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_carg.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargf.c b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
index 71c705d..6ea487c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cargl.c b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
index 96c3336..ba39438 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cargl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cargl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
index 0e609e1..4353d34 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrt.c
@@ -108,7 +108,7 @@
 	r=x/s;				/* error <= 0.5 ulps; |r| < |t| */
 	w=t+t;				/* t+t is exact */
 	r=(r-t)/(w+r);			/* r-t is exact; w+r ~= 3*t */
-	t=t+t*r;			/* error <= 0.5 + 0.5/3 + epsilon */
+	t=t+t*r;			/* error <= (0.5 + 0.5/3) * ulp */
 
 	return(t);
 }
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
index 2236c0f..b15c96e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cbrtl.c
@@ -136,7 +136,7 @@
 	r=x/s;				/* error <= 0.5 ulps; |r| < |t| */
 	w=t+t;				/* t+t is exact */
 	r=(r-t)/(w+r);			/* r-t is exact; w+r ~= 3*t */
-	t=t+t*r;			/* error <= 0.5 + 0.5/3 + epsilon */
+	t=t+t*r;			/* error <= (0.5 + 0.5/3) * ulp */
 
 	t *= v.e;
 	RETURNI(t);
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
index 7652b3c..0fd9206 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccosh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
index 5d7a09b..2db8403 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ccoshf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexp.c b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
index a1f853e..8db763d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexp.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexp.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
index d905b74..7247301 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cexpf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimag.c b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
index 1f383cb..0b14fd7 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimag.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimag.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
index 86a43c1..42a1efd 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
index 6d87950..9707bc3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cimagl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conj.c b/libm/upstream-freebsd/lib/msun/src/s_conj.c
index dc56f48..a83abd8 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conj.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjf.c b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
index 3fd8b8f..f9eb146 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_conjl.c b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
index d2f8d0f..4b86f2e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_conjl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_conjl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c b/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
index bd67447..666a2ba 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_copysignl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cosl.c b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
index 3d06648..6f0b36f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cosl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cosl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cospi.c b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
index 860219e..2e2f927 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cospi.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cospi.c
@@ -138,7 +138,8 @@
 		return (j0 & 1 ? -c : c);
 	}
 
-	if (ix >= 0x7f800000)
+	/* x = +-inf or nan. */
+	if (ix >= 0x7ff00000)
 		return (vzero / vzero);
 
 	/*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cproj.c b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
index 38e7747..5b0d4ed 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cproj.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cproj.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
index af4c3a8..0d76e75 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
index 16df514..7fc35d2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_cprojl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creal.c b/libm/upstream-freebsd/lib/msun/src/s_creal.c
index 69a10f2..5c8734e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creal.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_crealf.c b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
index 83e4d46..a93421f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_crealf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_crealf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_creall.c b/libm/upstream-freebsd/lib/msun/src/s_creall.c
index 538b7d5..b4eb9ef 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_creall.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_creall.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 Stefan Farfeleder
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinh.c b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
index 09b2dcb..b3928ce 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
index ba1a794..a8d6f2d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csinhf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
index d172efc..d96c344 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrt.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
index 6836a39..e3ef4d0 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
index 40bc59d..d564133 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_csqrtl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007-2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
index e5840a1..aa4e10c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanh.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
index c46f86d..e9ebe4f 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_ctanhf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2011 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2.c b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
index bc36e55..1dd9673 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_exp2.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c b/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
index c082924..c5b4c8e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_exp2f.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fdim.c b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
index c40c3e9..b81dbac 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fdim.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fdim.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fma.c b/libm/upstream-freebsd/lib/msun/src/s_fma.c
index 95cffd0..2fd7075 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fma.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fma.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
index 4591cc2..ae979cb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmal.c b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
index a379346..a0622a2 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmal.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmal.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmax.c b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
index b53b1e6..42bd11c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmax.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmax.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
index 8d3d14f..10667d3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
index c0d7c88..bf42587 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmaxl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fmin.c b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
index 53f36c1..e79071d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fmin.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fmin.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminf.c b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
index 58b6a48..19ffd42 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_fminl.c b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
index 97604b3..c906f1d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_fminl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_fminl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
index 66e284f..7101615 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_frexpl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lrint.c b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
index ad9b978..be00cbb 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lrint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lrint.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_lround.c b/libm/upstream-freebsd/lib/msun/src/s_lround.c
index 1dd8e69..00f4b95 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_lround.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_lround.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_modfl.c b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
index 2d83bbe..8e5c4d3 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_modfl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_modfl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nan.c b/libm/upstream-freebsd/lib/msun/src/s_nan.c
index 1769244..1345f22 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nan.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nan.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 David Schultz
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
index 796dbaf..ae6ffde 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_nearbyint.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_rintl.c b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
index 1e9824d..790edbc 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_rintl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_rintl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_round.c b/libm/upstream-freebsd/lib/msun/src/s_round.c
index ca25f8e..a112bc5 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_round.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_round.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundf.c b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
index 5bbf6b3..bb6f77c 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_roundl.c b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
index 8d1c02a..9e85423 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_roundl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_roundl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2003, Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
index c27420c..e8c6377 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_scalbln.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinl.c b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
index f1ef84c..c5ee106 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sinl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_sinpi.c b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
index 858459a..bc3759e 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_sinpi.c
@@ -155,7 +155,8 @@
 		return ((hx & 0x80000000) ? -s : s);
 	}
 
-	if (ix >= 0x7f800000)
+	/* x = +-inf or nan. */
+	if (ix >= 0x7ff00000)
 		return (vzero / vzero);
 
 	/*
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tanl.c b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
index 0c5228e..c21e38d 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tanl.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tanl.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2007 Steven G. Kargl
  * All rights reserved.
diff --git a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
index 1fd46e8..6cbd356 100644
--- a/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
+++ b/libm/upstream-freebsd/lib/msun/src/s_tgammaf.c
@@ -1,5 +1,5 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
  * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG>
  * All rights reserved.
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index a3f5246..fee19f4 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -97,7 +97,7 @@
                                     void* context) __LINKER_PUBLIC__;
 }
 
-static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
 static char* __bionic_set_dlerror(char* new_value) {
   char* old_value = __get_thread()->current_dlerror;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 5c26944..1553ba9 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -27,6 +27,7 @@
  */
 
 #include <android/api-level.h>
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
diff --git a/linker/linker_globals.h b/linker/linker_globals.h
index 0998629..0cb7ca9 100644
--- a/linker/linker_globals.h
+++ b/linker/linker_globals.h
@@ -104,3 +104,4 @@
 };
 
 __LIBC_HIDDEN__ extern bool g_is_ldd;
+__LIBC_HIDDEN__ extern pthread_mutex_t g_dl_mutex;
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f7c8ea9..e92aada 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -43,10 +43,11 @@
 #include "linker_tls.h"
 #include "linker_utils.h"
 
+#include "private/KernelArgumentBlock.h"
+#include "private/ScopedPthreadMutexLocker.h"
 #include "private/bionic_call_ifunc_resolver.h"
 #include "private/bionic_globals.h"
 #include "private/bionic_tls.h"
-#include "private/KernelArgumentBlock.h"
 
 #include "android-base/unique_fd.h"
 #include "android-base/strings.h"
@@ -498,6 +499,11 @@
 
   if (!get_cfi_shadow()->InitialLinkDone(solist)) __linker_cannot_link(g_argv[0]);
 
+  // A constructor could spawn a thread that calls into the loader, so as soon
+  // as we've called a constructor, we need to hold the lock while accessing
+  // global loader state.
+  ScopedPthreadMutexLocker locker(&g_dl_mutex);
+
   si->call_pre_init_constructors();
   si->call_constructors();
 
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index 456d254..7ce53b8 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -76,6 +76,10 @@
   return get_allocator().memalign(alignment, byte_count);
 }
 
+void* aligned_alloc(size_t alignment, size_t byte_count) {
+  return get_allocator().memalign(alignment, byte_count);
+}
+
 void* calloc(size_t item_count, size_t item_size) {
   return get_allocator().alloc(item_count*item_size);
 }
diff --git a/tests/Android.bp b/tests/Android.bp
index 36a3a37..a4298ab 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -470,7 +470,9 @@
         "struct_layout_test.cpp",
         "sstream_test.cpp",
         "sys_auxv_test.cpp",
+        "sys_cachectl_test.cpp",
         "sys_epoll_test.cpp",
+        "sys_hwprobe_test.cpp",
         "sys_mman_test.cpp",
         "sys_msg_test.cpp",
         "sys_param_test.cpp",
diff --git a/tests/fcntl_test.cpp b/tests/fcntl_test.cpp
index 862f498..c1c586c 100644
--- a/tests/fcntl_test.cpp
+++ b/tests/fcntl_test.cpp
@@ -360,6 +360,6 @@
 #endif
 }
 
-TEST(fcntl_DeathTest, fcntl_F_SETFD) {
+TEST_F(fcntl_DeathTest, fcntl_F_SETFD) {
   EXPECT_DEATH(fcntl(0, F_SETFD, O_NONBLOCK), "non-FD_CLOEXEC");
 }
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index c31f48c..709a939 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -34,12 +34,15 @@
 #if defined(__BIONIC__)
 
 #include "android-base/file.h"
+#include "android-base/silent_death_test.h"
 #include "android-base/test_utils.h"
 #include "gwp_asan/options.h"
 #include "platform/bionic/malloc.h"
 #include "sys/system_properties.h"
 #include "utils.h"
 
+using gwp_asan_integration_DeathTest = SilentDeathTest;
+
 // basename is a mess, use gnu basename explicitly to avoid the need for string
 // mutation.
 extern "C" const char* __gnu_basename(const char* path);
@@ -133,7 +136,7 @@
   }
 };
 
-TEST(gwp_asan_integration, DISABLED_assert_gwp_asan_enabled) {
+TEST_F(gwp_asan_integration_DeathTest, DISABLED_assert_gwp_asan_enabled) {
   std::string maps;
   EXPECT_TRUE(android::base::ReadFileToString("/proc/self/maps", &maps));
   EXPECT_TRUE(maps.find("GWP-ASan") != std::string::npos) << maps;
@@ -173,7 +176,7 @@
   __system_property_set((std::string("libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                         "40000");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_persist_program_specific) {
@@ -191,7 +194,7 @@
   __system_property_set((std::string("persist.libc.debug.gwp_asan.max_allocs.") + basename).c_str(),
                         "40000");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
@@ -235,7 +238,7 @@
   __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
   __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
 
-  RunSubtestNoEnv("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunSubtestNoEnv("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 TEST(gwp_asan_integration, sysprops_can_disable) {
@@ -261,7 +264,7 @@
   __system_property_set("libc.debug.gwp_asan.process_sampling.system_default", "0");
   __system_property_set("libc.debug.gwp_asan.max_allocs.system_default", "0");
 
-  RunGwpAsanTest("gwp_asan_integration.DISABLED_assert_gwp_asan_enabled");
+  RunGwpAsanTest("gwp_asan_integration_DeathTest.DISABLED_assert_gwp_asan_enabled");
 }
 
 #endif  // defined(__BIONIC__)
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index 5d85e97..b88d64a 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -19,6 +19,8 @@
 #include <malloc.h>
 #include <sys/prctl.h>
 
+#include <android-base/silent_death_test.h>
+
 #if defined(__BIONIC__)
 #include "gtest_globals.h"
 #include "platform/bionic/mte.h"
@@ -44,7 +46,9 @@
 }
 #endif
 
-TEST(heap_tagging_level, tagged_pointer_dies) {
+using heap_tagging_level_DeathTest = SilentDeathTest;
+
+TEST_F(heap_tagging_level_DeathTest, tagged_pointer_dies) {
 #if defined(__BIONIC__)
   if (!KernelSupportsTaggedPointers()) {
     GTEST_SKIP() << "Kernel doesn't support tagged pointers.";
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 5df694c..2dbc680 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -1347,44 +1347,43 @@
 }
 
 #if defined(__BIONIC__)
-static void* SetAllocationLimit(void* data) {
-  std::atomic_bool* go = reinterpret_cast<std::atomic_bool*>(data);
-  while (!go->load()) {
-  }
-  size_t limit = 500 * 1024 * 1024;
-  if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
-    return reinterpret_cast<void*>(-1);
-  }
-  return nullptr;
-}
-
 static void SetAllocationLimitMultipleThreads() {
-  std::atomic_bool go;
-  go = false;
-
   static constexpr size_t kNumThreads = 4;
-  pthread_t threads[kNumThreads];
+  std::atomic_bool start_running = false;
+  std::atomic<size_t> num_running;
+  std::atomic<size_t> num_successful;
+  std::unique_ptr<std::thread> threads[kNumThreads];
   for (size_t i = 0; i < kNumThreads; i++) {
-    ASSERT_EQ(0, pthread_create(&threads[i], nullptr, SetAllocationLimit, &go));
+    threads[i].reset(new std::thread([&num_running, &start_running, &num_successful] {
+      ++num_running;
+      while (!start_running) {
+      }
+      size_t limit = 500 * 1024 * 1024;
+      if (android_mallopt(M_SET_ALLOCATION_LIMIT_BYTES, &limit, sizeof(limit))) {
+        ++num_successful;
+      }
+    }));
   }
 
-  // Let them go all at once.
-  go = true;
+  // Wait until all of the threads have started.
+  while (num_running != kNumThreads)
+    ;
+
+  // Now start all of the threads setting the mallopt at once.
+  start_running = true;
+
   // Send hardcoded signal (BIONIC_SIGNAL_PROFILER with value 0) to trigger
-  // heapprofd handler.
-  union sigval signal_value;
-  signal_value.sival_int = 0;
+  // heapprofd handler. This will verify that changing the limit while
+  // the allocation handlers are being changed at the same time works,
+  // or that the limit handler is changed first and this also works properly.
+  union sigval signal_value {};
   ASSERT_EQ(0, sigqueue(getpid(), BIONIC_SIGNAL_PROFILER, signal_value));
 
-  size_t num_successful = 0;
+  // Wait for all of the threads to finish.
   for (size_t i = 0; i < kNumThreads; i++) {
-    void* result;
-    ASSERT_EQ(0, pthread_join(threads[i], &result));
-    if (result != nullptr) {
-      num_successful++;
-    }
+    threads[i]->join();
   }
-  ASSERT_EQ(1U, num_successful);
+  ASSERT_EQ(1U, num_successful) << "Only one thread should be able to set the limit.";
   exit(0);
 }
 #endif
diff --git a/tests/run-on-host.sh b/tests/run-on-host.sh
index fe2c25a..19bbacf 100755
--- a/tests/run-on-host.sh
+++ b/tests/run-on-host.sh
@@ -2,9 +2,14 @@
 
 . $(dirname $0)/../build/run-on-host.sh
 
-if [ "$1" = glibc ]; then
+if [ "$1" = glibc -o "$1" = musl ]; then
+  if [ "$1" = musl ]; then
+    BUILD_ARGS=USE_HOST_MUSL=true
+  else
+    BUILD_ARGS=
+  fi
   shift
-  m -j bionic-unit-tests-glibc
+  m -j $BUILD_ARGS bionic-unit-tests-glibc
   (
     cd ${ANDROID_BUILD_TOP}
     export ANDROID_DATA=${TARGET_OUT_DATA}
@@ -13,7 +18,7 @@
   )
   exit 0
 elif [ "$1" != 32 -a "$1" != 64 ]; then
-  echo "Usage: $0 [ 32 | 64 | glibc ] [gtest flags]"
+  echo "Usage: $0 [ 32 | 64 | glibc | musl ] [gtest flags]"
   exit 1
 fi
 
diff --git a/tests/scs_test.cpp b/tests/scs_test.cpp
index 0776a43..3d5ebc1 100644
--- a/tests/scs_test.cpp
+++ b/tests/scs_test.cpp
@@ -16,8 +16,12 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/silent_death_test.h>
+
 #include "private/bionic_constants.h"
 
+using scs_DeathTest = SilentDeathTest;
+
 int recurse2(int count);
 
 __attribute__((weak, noinline)) int recurse1(int count) {
@@ -30,7 +34,7 @@
   return 0;
 }
 
-TEST(scs_test, stack_overflow) {
+TEST_F(scs_DeathTest, stack_overflow) {
 #if defined(__aarch64__) || defined(__riscv)
   ASSERT_EXIT(recurse1(SCS_SIZE), testing::KilledBySignal(SIGSEGV), "");
 #else
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index fa648d2..2e6908c 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -530,14 +530,15 @@
 #endif
 }
 
-#if defined(__BIONIC__)
+#if defined(__BIONIC__) && !defined(__riscv)
 // Not exposed via headers, but the symbols are available if you declare them yourself.
 extern "C" int sigblock(int);
 extern "C" int sigsetmask(int);
+#define HAVE_SIGBLOCK_SIGSETMASK
 #endif
 
 TEST(signal, sigblock_filter) {
-#if defined(__BIONIC__)
+#if defined(HAVE_SIGBLOCK_SIGSETMASK)
   TestSignalMaskFunction([]() {
     sigblock(~0U);
   });
@@ -545,7 +546,7 @@
 }
 
 TEST(signal, sigsetmask_filter) {
-#if defined(__BIONIC__)
+#if defined(HAVE_SIGBLOCK_SIGSETMASK)
   TestSignalMaskFunction([]() {
     sigsetmask(~0U);
   });
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index b3a296d..b0f59bb 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -1049,11 +1049,13 @@
 }
 
 TEST(STDIO_TEST, popen_return_value_signal) {
-  FILE* fp = popen("kill -7 $$", "r");
+  // Use a realtime signal to avoid creating a tombstone when running.
+  std::string cmd = android::base::StringPrintf("kill -%d $$", SIGRTMIN);
+  FILE* fp = popen(cmd.c_str(), "r");
   ASSERT_TRUE(fp != nullptr);
   int status = pclose(fp);
   EXPECT_TRUE(WIFSIGNALED(status));
-  EXPECT_EQ(7, WTERMSIG(status));
+  EXPECT_EQ(SIGRTMIN, WTERMSIG(status));
 }
 
 TEST(STDIO_TEST, getc) {
@@ -3310,7 +3312,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_invalid_w_width) {
+TEST_F(STDIO_DEATHTEST, snprintf_invalid_w_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
@@ -3323,7 +3325,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_invalid_w_width) {
+TEST_F(STDIO_DEATHTEST, swprintf_invalid_w_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat-invalid-specifier"
@@ -3459,7 +3461,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, snprintf_invalid_wf_width) {
+TEST_F(STDIO_DEATHTEST, snprintf_invalid_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3473,7 +3475,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swprintf_invalid_wf_width) {
+TEST_F(STDIO_DEATHTEST, swprintf_invalid_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3572,7 +3574,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, sscanf_invalid_w_or_wf_width) {
+TEST_F(STDIO_DEATHTEST, sscanf_invalid_w_or_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
@@ -3672,7 +3674,7 @@
 #endif
 }
 
-TEST(STDIO_TEST, swscanf_invalid_w_or_wf_width) {
+TEST_F(STDIO_DEATHTEST, swscanf_invalid_w_or_wf_width) {
 #if defined(__BIONIC__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wformat"
diff --git a/tests/sys_cachectl_test.cpp b/tests/sys_cachectl_test.cpp
new file mode 100644
index 0000000..d9ece4f
--- /dev/null
+++ b/tests/sys_cachectl_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#if __has_include(<sys/cachectl.h>)
+#include <sys/cachectl.h>
+#endif
+
+TEST(sys_cachectl, __riscv_flush_icache) {
+#if defined(__riscv) && __has_include(<sys/cachectl.h>)
+  // As of Linux 6.4, the address range is ignored (so nullptr is fine),
+  // and the flags you actually want are 0 ("all threads"),
+  // but we test the unusual flag just to make sure it works.
+  ASSERT_EQ(0, __riscv_flush_icache(nullptr, nullptr, SYS_RISCV_FLUSH_ICACHE_LOCAL));
+#else
+  GTEST_SKIP() << "__riscv_flush_icache requires riscv64";
+#endif
+}
diff --git a/tests/sys_hwprobe_test.cpp b/tests/sys_hwprobe_test.cpp
new file mode 100644
index 0000000..15028ff
--- /dev/null
+++ b/tests/sys_hwprobe_test.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <gtest/gtest.h>
+
+#if __has_include(<sys/hwprobe.h>)
+#include <sys/hwprobe.h>
+#endif
+
+TEST(sys_hwprobe, __riscv_hwprobe) {
+#if defined(__riscv) && __has_include(<sys/cachectl.h>)
+  riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_IMA_EXT_0},
+                            {.key = RISCV_HWPROBE_KEY_CPUPERF_0}};
+  ASSERT_EQ(0, __riscv_hwprobe(probes, 2, 0, nullptr, 0));
+  EXPECT_EQ(RISCV_HWPROBE_KEY_IMA_EXT_0, probes[0].key);
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_FD) != 0);
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_C) != 0);
+  // TODO: remove #define when our uapi headers are new enough.
+#define RISCV_HWPROBE_IMA_V (1 << 2)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_IMA_V) != 0);
+  // TODO: remove #ifs when our kernel is new enough.
+#if defined(RISCV_HWPROBE_EXT_ZBA)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBA) != 0);
+#endif
+#if defined(RISCV_HWPROBE_EXT_ZBB)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBB) != 0);
+#endif
+#if defined(RISCV_HWPROBE_EXT_ZBS)
+  EXPECT_TRUE((probes[0].value & RISCV_HWPROBE_EXT_ZBS) != 0);
+#endif
+
+  EXPECT_EQ(RISCV_HWPROBE_KEY_CPUPERF_0, probes[1].key);
+  EXPECT_TRUE((probes[1].value & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST);
+#else
+  GTEST_SKIP() << "__riscv_hwprobe requires riscv64";
+#endif
+}
diff --git a/tests/uchar_test.cpp b/tests/uchar_test.cpp
index 4dc6314..9e42f58 100644
--- a/tests/uchar_test.cpp
+++ b/tests/uchar_test.cpp
@@ -24,22 +24,89 @@
 #include <locale.h>
 #include <stdint.h>
 
+// Modern versions of UTF-8 (https://datatracker.ietf.org/doc/html/rfc3629 and
+// newer) explicitly disallow code points beyond U+10FFFF, which exclude all 5-
+// and 6-byte sequences. Earlier versions of UTF-8 allowed the wider range:
+// https://datatracker.ietf.org/doc/html/rfc2279.
+//
+// Bionic's unicode implementation was written after the high values were
+// excluded, so it has never supported them. Other implementations (at least
+// as of glibc 2.36), do support those sequences.
+#if defined(__ANDROID__) || defined(ANDROID_HOST_MUSL)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = true;
+#elif defined(__GLIBC__)
+constexpr bool kLibcRejectsOverLongUtf8Sequences = false;
+#else
+#error kLibcRejectsOverLongUtf8Sequences must be configured for this platform
+#endif
+
+// C23 7.30.1 (for each `mbrtoc*` function) says:
+//
+// Returns:
+//
+//     0 if the next n or fewer bytes complete the multibyte character that
+//     corresponds to the null wide character (which is the value stored).
+//
+//     (size_t)(-2) if the next n bytes contribute to an incomplete (but
+//     potentially valid) multibyte character, and all n bytes have been
+//     processed (no value is stored).
+//
+// Bionic historically interpreted the behavior when n is 0 to be the next 0
+// bytes decoding to the null. That's a pretty bad interpretation, and both
+// glibc and musl return -2 for that case.
+//
+// The tests currently checks the incorrect behavior for bionic because gtest
+// doesn't support explicit xfail annotations. The behavior difference here
+// should be fixed, but danalbert wants to add more tests before tackling the
+// bugs.
+#ifdef __ANDROID__
+constexpr size_t kExpectedResultForZeroLength = 0U;
+#else
+constexpr size_t kExpectedResultForZeroLength = static_cast<size_t>(-2);
+#endif
+
 TEST(uchar, sizeof_uchar_t) {
   EXPECT_EQ(2U, sizeof(char16_t));
   EXPECT_EQ(4U, sizeof(char32_t));
 }
 
 TEST(uchar, start_state) {
+  // C23 does not appear to specify the behavior of the conversion functions if
+  // a state is reused before the character is completed. In the wchar.h section
+  // (7.31.6.3) it says:
+  //
+  //     If an mbstate_t object has been altered by any of the functions
+  //     described in this subclause, and is then used with a different
+  //     multibyte character sequence, or in the other conversion direction, or
+  //     with a different LC_CTYPE category setting than on earlier function
+  //     calls, the behavior is undefined.
+  //
+  // But "described in this subclause" refers to the wchar.h functions, not the
+  // uchar.h ones.
+  //
+  // Since C has no opinion, we need to make a choice. While no caller should
+  // ever do this (what does it mean to begin decoding a UTF-32 character while
+  // still in the middle of a UTF-8 sequence?), considering that a decoding
+  // error seems the least surprising. Bionic and glibc both have that behavior.
+  // musl ignores the state (it also doesn't make much sense to read the state
+  // when the entire conversion completes in a single call) and decodes the
+  // UTF-32 character.
+#if !defined(ANDROID_HOST_MUSL)
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char out[MB_LEN_MAX];
   mbstate_t ps;
 
-  // Any non-initial state is invalid when calling c32rtomb.
   memset(&ps, 0, sizeof(ps));
   EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xc2", 1, &ps));
   errno = 0;
   EXPECT_EQ(static_cast<size_t>(-1), c32rtomb(out, 0x00a2, &ps));
   EXPECT_EQ(EILSEQ, errno);
 
+  // Similarly (but not in compliance with the standard afaict), musl seems to
+  // ignore the state entirely for the UTF-32 functions rather than reset it.
+
   // If the first argument to c32rtomb is nullptr or the second is L'\0' the shift
   // state should be reset.
   memset(&ps, 0, sizeof(ps));
@@ -51,14 +118,21 @@
   EXPECT_EQ(static_cast<size_t>(-2), mbrtoc32(nullptr, "\xf0\xa4", 1, &ps));
   EXPECT_EQ(1U, c32rtomb(out, L'\0', &ps));
   EXPECT_TRUE(mbsinit(&ps));
+#endif
 }
 
 TEST(uchar, c16rtomb_null_out) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   EXPECT_EQ(1U, c16rtomb(nullptr, L'\0', nullptr));
   EXPECT_EQ(1U, c16rtomb(nullptr, L'h', nullptr));
 }
 
 TEST(uchar, c16rtomb_null_char) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char bytes[MB_LEN_MAX];
   EXPECT_EQ(1U, c16rtomb(bytes, L'\0', nullptr));
 }
@@ -99,6 +173,9 @@
 }
 
 TEST(uchar, c16rtomb_invalid) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char bytes[MB_LEN_MAX];
 
   memset(bytes, 0, sizeof(bytes));
@@ -109,20 +186,26 @@
 }
 
 TEST(uchar, mbrtoc16_null) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   ASSERT_EQ(0U, mbrtoc16(nullptr, nullptr, 0, nullptr));
 }
 
 TEST(uchar, mbrtoc16_zero_len) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   char16_t out;
 
   out = L'x';
-  ASSERT_EQ(0U, mbrtoc16(&out, "hello", 0, nullptr));
-  ASSERT_EQ(L'x', out);
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc16(&out, "hello", 0, nullptr));
+  EXPECT_EQ(L'x', out);
 
-  ASSERT_EQ(0U, mbrtoc16(&out, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc16(&out, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc16(&out, "hello", 1, nullptr));
-  ASSERT_EQ(L'h', out);
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc16(&out, "hello", 0, nullptr));
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc16(&out, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc16(&out, "hello", 1, nullptr));
+  EXPECT_EQ(L'h', out);
 }
 
 TEST(uchar, mbrtoc16) {
@@ -141,27 +224,87 @@
   ASSERT_EQ(3U, mbrtoc16(&out, "\xe2\x82\xac" "def", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0x20ac), out);
   // 4-byte UTF-8 will be returned as a surrogate pair...
+#ifdef __BIONIC__
+  // https://issuetracker.google.com/289419882
+  //
+  // We misread the spec when implementing this. The first call should return
+  // the length of the decoded character, and the second call should return -3
+  // to indicate that the output is a continuation of the character decoded by
+  // the first call.
+  //
+  // C23 7.30.1.3.4:
+  //
+  //     between 1 and n inclusive if the next n or fewer bytes complete a valid
+  //     multibyte character (which is the value stored); the value returned is
+  //     the number of bytes that complete the multibyte character.
+  //
+  //     (size_t)(-3) if the next character resulting from a previous call has
+  //     been stored (no bytes from the input have been consumed by this call).
+  //
+  // Leaving the test for the wrong outputs here while we clean up and improve
+  // the rest of the tests to get a better handle on the behavior differences
+  // before fixing the bug.
   ASSERT_EQ(static_cast<size_t>(-3),
             mbrtoc16(&out, "\xf4\x8a\xaf\x8d", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
   ASSERT_EQ(4U, mbrtoc16(&out, "\xf4\x8a\xaf\x8d" "ef", 6, nullptr));
   ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
-  // Illegal 5-byte UTF-8.
+#else
+  ASSERT_EQ(4U, mbrtoc16(&out, "\xf4\x8a\xaf\x8d", 6, nullptr));
+  ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
+  ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out,
+                                              "\xf4\x8a\xaf\x8d"
+                                              "ef",
+                                              6, nullptr));
+  ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
+#endif
+}
+
+TEST(uchar, mbrtoc16_long_sequences) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  char16_t out = u'\0';
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\xf8\xa1\xa2\xa3\xa4", 5, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  auto result = mbrtoc16(&out, "\xf8\xa1\xa2\xa3\xa4", 5, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(EILSEQ, errno);
+    EXPECT_EQ(u'\0', out);
+  } else {
+    EXPECT_EQ(5U, result);
+    EXPECT_EQ(0, errno);
+    EXPECT_EQ(u'\uf94a', out);
+  }
 }
 
 TEST(uchar, mbrtoc16_reserved_range) {
-  char16_t out;
-  ASSERT_EQ(static_cast<size_t>(-1),
-            mbrtoc16(&out, "\xf0\x80\xbf\xbf", 6, nullptr));
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  errno = 0;
+  char16_t out = u'\0';
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc16(&out, "\xf0\x80\xbf\xbf", 6, nullptr));
+  EXPECT_EQ(u'\0', out);
+  EXPECT_EQ(EILSEQ, errno);
 }
 
 TEST(uchar, mbrtoc16_beyond_range) {
-  char16_t out;
-  ASSERT_EQ(static_cast<size_t>(-1),
-            mbrtoc16(&out, "\xf5\x80\x80\x80", 6, nullptr));
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
+  errno = 0;
+  char16_t out = u'\0';
+  auto result = mbrtoc16(&out, "\xf5\x80\x80\x80", 6, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(u'\0', out);
+    EXPECT_EQ(EILSEQ, errno);
+  } else {
+    EXPECT_EQ(4U, result);
+    EXPECT_EQ(u'\xdcc0', out);
+    EXPECT_EQ(0, errno);
+  }
 }
 
 void test_mbrtoc16_incomplete(mbstate_t* ps) {
@@ -183,10 +326,25 @@
   // 4-byte UTF-8.
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "\xf4", 1, ps));
   ASSERT_EQ(static_cast<size_t>(-2), mbrtoc16(&out, "\x8a\xaf", 2, ps));
+#ifdef __BIONIC__
+  // https://issuetracker.google.com/289419882
+  // See explanation in mbrtoc16 test for the same bug.
   ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out, "\x8d" "ef", 3, ps));
   ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
   ASSERT_EQ(1U, mbrtoc16(&out, "\x80" "ef", 3, ps));
   ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
+#else
+  ASSERT_EQ(1U, mbrtoc16(&out,
+                         "\x8d"
+                         "ef",
+                         3, ps));
+  ASSERT_EQ(static_cast<char16_t>(0xdbea), out);
+  ASSERT_EQ(static_cast<size_t>(-3), mbrtoc16(&out,
+                                              "\x80"
+                                              "ef",
+                                              3, ps));
+  ASSERT_EQ(static_cast<char16_t>(0xdfcd), out);
+#endif
   ASSERT_TRUE(mbsinit(ps));
 
   // Invalid 2-byte
@@ -197,6 +355,9 @@
 }
 
 TEST(uchar, mbrtoc16_incomplete) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   mbstate_t ps;
   memset(&ps, 0, sizeof(ps));
 
@@ -265,55 +426,78 @@
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
-  char32_t out[8] = {};
+  char32_t out = U'\0';
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf5\x80\x80\x80", 4, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  auto result = mbrtoc32(&out, "\xf5\x80\x80\x80", 4, nullptr);
+  if (kLibcRejectsOverLongUtf8Sequences) {
+    EXPECT_EQ(static_cast<size_t>(-1), result);
+    EXPECT_EQ(EILSEQ, errno);
+    EXPECT_EQ(U'\0', out);
+  } else {
+    EXPECT_EQ(4U, result);
+    EXPECT_EQ(0, errno);
+    EXPECT_EQ(U'\x140000', out);
+  }
 }
 
 TEST(uchar, mbrtoc32) {
   char32_t out[8];
 
   out[0] = L'x';
-  ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'x'), out[0]);
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc32(out, "hello", 0, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'x'), out[0]);
 
-  ASSERT_EQ(0U, mbrtoc32(out, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc32(out, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'h'), out[0]);
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc32(out, "hello", 0, nullptr));
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc32(out, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc32(out, "hello", 1, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'h'), out[0]);
 
-  ASSERT_EQ(0U, mbrtoc32(nullptr, "hello", 0, nullptr));
-  ASSERT_EQ(0U, mbrtoc32(nullptr, "", 0, nullptr));
-  ASSERT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr));
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc32(nullptr, "hello", 0, nullptr));
+  EXPECT_EQ(kExpectedResultForZeroLength, mbrtoc32(nullptr, "", 0, nullptr));
+  EXPECT_EQ(1U, mbrtoc32(nullptr, "hello", 1, nullptr));
 
-  ASSERT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr));
+  EXPECT_EQ(0U, mbrtoc32(nullptr, nullptr, 0, nullptr));
 
   ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
   uselocale(LC_GLOBAL_LOCALE);
 
   // 1-byte UTF-8.
-  ASSERT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(L'a'), out[0]);
+  EXPECT_EQ(1U, mbrtoc32(out, "abcdef", 6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(L'a'), out[0]);
   // 2-byte UTF-8.
-  ASSERT_EQ(2U, mbrtoc32(out, "\xc2\xa2" "cdef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x00a2), out[0]);
+  EXPECT_EQ(2U, mbrtoc32(out,
+                         "\xc2\xa2"
+                         "cdef",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x00a2), out[0]);
   // 3-byte UTF-8.
-  ASSERT_EQ(3U, mbrtoc32(out, "\xe2\x82\xac" "def", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x20ac), out[0]);
+  EXPECT_EQ(3U, mbrtoc32(out,
+                         "\xe2\x82\xac"
+                         "def",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x20ac), out[0]);
   // 4-byte UTF-8.
-  ASSERT_EQ(4U, mbrtoc32(out, "\xf0\xa4\xad\xa2" "ef", 6, nullptr));
-  ASSERT_EQ(static_cast<char32_t>(0x24b62), out[0]);
+  EXPECT_EQ(4U, mbrtoc32(out,
+                         "\xf0\xa4\xad\xa2"
+                         "ef",
+                         6, nullptr));
+  EXPECT_EQ(static_cast<char32_t>(0x24b62), out[0]);
 #if defined(__BIONIC__) // glibc allows this.
   // Illegal 5-byte UTF-8.
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf8\xa1\xa2\xa3\xa4" "f", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out,
+                                              "\xf8\xa1\xa2\xa3\xa4"
+                                              "f",
+                                              6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 #endif
   // Illegal over-long sequence.
   errno = 0;
-  ASSERT_EQ(static_cast<size_t>(-1), mbrtoc32(out, "\xf0\x82\x82\xac" "ef", 6, nullptr));
-  ASSERT_EQ(EILSEQ, errno);
+  EXPECT_EQ(static_cast<size_t>(-1), mbrtoc32(out,
+                                              "\xf0\x82\x82\xac"
+                                              "ef",
+                                              6, nullptr));
+  EXPECT_EQ(EILSEQ, errno);
 }
 
 void test_mbrtoc32_incomplete(mbstate_t* ps) {
@@ -347,6 +531,9 @@
 }
 
 TEST(uchar, mbrtoc32_incomplete) {
+  ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8"));
+  uselocale(LC_GLOBAL_LOCALE);
+
   mbstate_t ps;
   memset(&ps, 0, sizeof(ps));