Merge "[HWASan] [16k] do not instrument getauxval" into main
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 888404c..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/README.md b/README.md
index 0ad06a8..0f2c30f 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,11 @@
-# bionic
+# bionic maintainer overview
[bionic](https://en.wikipedia.org/wiki/Bionic_(software)) is Android's
C library, math library, and dynamic linker.
-# Using bionic as an app developer
-
-See the [user documentation](docs/).
-
-# Working on bionic itself
-
-This documentation is about making changes to bionic itself.
+This document is a high-level overview of making changes to bionic itself.
+If you're trying to _use_ bionic, or want more in-depth information about
+some part of the implementation, see [all the bionic documentation](docs/).
## What are the big pieces of bionic?
diff --git a/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h b/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
index 885e47f..ea63e36 100644
--- a/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
+++ b/benchmarks/linker_relocation/include/linker_reloc_bench_asm.h
@@ -44,9 +44,7 @@
#elif defined(__riscv)
-// No `lga` in clang unless https://reviews.llvm.org/D107278 lands.
-// `la` is equivalent when using PIC (which we do) though.
-#define GOT_RELOC(sym) la a0, sym
+#define GOT_RELOC(sym) lga a0, sym
#define CALL(sym) call sym@plt
#define DATA_WORD(val) .quad val
#define MAIN .globl main; main: li a0, 0; ret
diff --git a/benchmarks/util.h b/benchmarks/util.h
index 99eed5f..347dc35 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -71,7 +71,7 @@
bool LockToCPU(int cpu_to_lock);
-static __inline __attribute__ ((__always_inline__)) void MakeAllocationResident(
+static inline __attribute__((__always_inline__)) void MakeAllocationResident(
void* ptr, size_t nbytes, int pagesize) {
uint8_t* data = reinterpret_cast<uint8_t*>(ptr);
for (size_t i = 0; i < nbytes; i += pagesize) {
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..2825eac
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,34 @@
+# bionic documentation
+
+[bionic](https://en.wikipedia.org/wiki/Bionic_(software)) is Android's
+C library, math library, and dynamic linker.
+
+## User documentation
+
+* [Android bionic status](status.md) - where we are in terms of standards,
+ and what changed with each OS release.
+* [32-bit ABI bugs](32-bit-abi.md) - historical accidents we can never fix.
+* [`EINTR`](EINTR.md) - what is the `EINTR` failure,
+ and how can code deal with it?
+* [When to use which `#define`](defines.md) - how to choose between
+ `__ANDROID__` and `__BIONIC__` and all the other options for conditional
+ compilation.
+* [fdsan](fdsan.md) - bionic's file descriptor sanitizer,
+ which detects use-after-close() bugs.
+* [fdtrack](fdtrack.md) - bionic's file descriptor tracker,
+ which helps debug file descriptor leaks.
+
+## Maintainer documentation
+
+If you're trying to make changes to bionic _itself_, start with the
+[bionic maintainer documentation](../README.md).
+
+We also have more detail on several specific parts of the implementation:
+
+* [The anatomy of bionic's `_FORTIFY_SOURCE`](clang_fortify_anatomy.md) -
+ how does `_FORTIFY_SOURCE` work on bionic (primarily "with clang").
+* [Android ELF TLS](elf-tls.md) - details of bionic's ELF TLS implementation.
+* [Validating libc assembler](libc_assembler.md) - how to test changes to
+ libc assembler routines.
+* [Validating native allocator changes](native_allocator.md) - how to test
+ changes to the native allocator.
diff --git a/libc/Android.bp b/libc/Android.bp
index 2efca68..d8467a8 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1224,9 +1224,6 @@
// off64_t/time64_t support on LP32.
"bionic/legacy_32_bit_support.cpp",
"bionic/time64.c",
-
- // TODO: move to libc/bionic/legacy_32_bit_support.cpp or #if __LP64__ instead.
- "bionic/mmap.cpp",
],
},
},
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 0db5d79..ce14e49 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -174,20 +174,21 @@
off_t lseek(int, off_t, int) lp32
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) lp32
off_t lseek|lseek64(int, off_t, int) lp64
-int ftruncate64(int, off64_t) lp32
-int ftruncate|ftruncate64(int, off_t) lp64
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) lp32
ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count) lp32
ssize_t sendfile|sendfile64(int out_fd, int in_fd, off_t* offset, size_t count) lp64
int truncate(const char*, off_t) lp32
int truncate64(const char*, off64_t) lp32
int truncate|truncate64(const char*, off_t) lp64
-# (mmap only gets two lines because we only used the 64-bit variant on 32-bit systems.)
-void* __mmap2:mmap2(void*, size_t, int, int, int, long) lp32
-void* mmap|mmap64(void*, size_t, int, int, int, off_t) lp64
# (fallocate only gets two lines because there is no 32-bit variant.)
int fallocate64:fallocate(int, int, off64_t, off64_t) lp32
int fallocate|fallocate64(int, int, off_t, off_t) lp64
+# (ftruncate only gets two lines because 32-bit bionic only uses the 64-bit call.)
+int ftruncate64(int, off64_t) lp32
+int ftruncate|ftruncate64(int, off_t) lp64
+# (mmap only gets two lines because 32-bit bionic only uses the 64-bit call.)
+void* __mmap2:mmap2(void*, size_t, int, int, int, long) lp32
+void* mmap|mmap64(void*, size_t, int, int, int, off_t) lp64
# posix_fadvise64 is awkward: arm has shuffled arguments,
# the POSIX functions don't set errno, and no architecture has posix_fadvise.
diff --git a/libc/bionic/bionic_allocator.cpp b/libc/bionic/bionic_allocator.cpp
index 80e8b08..41baf8b 100644
--- a/libc/bionic/bionic_allocator.cpp
+++ b/libc/bionic/bionic_allocator.cpp
@@ -299,7 +299,7 @@
log2_size = kSmallObjectMinSizeLog2;
}
- return get_small_object_allocator(log2_size)->alloc();
+ return get_small_object_allocator_unchecked(log2_size)->alloc();
}
void* BionicAllocator::alloc(size_t size) {
@@ -330,9 +330,10 @@
inline page_info* BionicAllocator::get_page_info(void* ptr) {
page_info* info = get_page_info_unchecked(ptr);
if (memcmp(info->signature, kSignature, sizeof(kSignature)) != 0) {
- async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
+ async_safe_fatal("invalid pointer %p (page signature %04x instead of %04x)", ptr,
+ *reinterpret_cast<const unsigned*>(info->signature),
+ *reinterpret_cast<const unsigned*>(kSignature));
}
-
return info;
}
@@ -353,12 +354,7 @@
if (info->type == kLargeObject) {
old_size = info->allocated_size - (static_cast<char*>(ptr) - reinterpret_cast<char*>(info));
} else {
- BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
- if (allocator != info->allocator_addr) {
- async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr);
- }
-
- old_size = allocator->get_block_size();
+ old_size = get_small_object_allocator(info, ptr)->get_block_size();
}
if (old_size < size) {
@@ -377,16 +373,10 @@
}
page_info* info = get_page_info(ptr);
-
if (info->type == kLargeObject) {
munmap(info, info->allocated_size);
} else {
- BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
- if (allocator != info->allocator_addr) {
- async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr);
- }
-
- allocator->free(ptr);
+ get_small_object_allocator(info, ptr)->free(ptr);
}
}
@@ -402,7 +392,7 @@
return info->allocated_size - (static_cast<char*>(ptr) - reinterpret_cast<char*>(info));
}
- BionicSmallObjectAllocator* allocator = get_small_object_allocator(info->type);
+ BionicSmallObjectAllocator* allocator = get_small_object_allocator_unchecked(info->type);
if (allocator != info->allocator_addr) {
// Invalid pointer.
return 0;
@@ -410,7 +400,7 @@
return allocator->get_block_size();
}
-BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator(uint32_t type) {
+BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator_unchecked(uint32_t type) {
if (type < kSmallObjectMinSizeLog2 || type > kSmallObjectMaxSizeLog2) {
async_safe_fatal("invalid type: %u", type);
}
@@ -418,3 +408,11 @@
initialize_allocators();
return &allocators_[type - kSmallObjectMinSizeLog2];
}
+
+BionicSmallObjectAllocator* BionicAllocator::get_small_object_allocator(page_info* pi, void* ptr) {
+ BionicSmallObjectAllocator* result = get_small_object_allocator_unchecked(pi->type);
+ if (result != pi->allocator_addr) {
+ async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr);
+ }
+ return result;
+}
\ No newline at end of file
diff --git a/libc/bionic/bionic_elf_tls.cpp b/libc/bionic/bionic_elf_tls.cpp
index a053c27..3245b90 100644
--- a/libc/bionic/bionic_elf_tls.cpp
+++ b/libc/bionic/bionic_elf_tls.cpp
@@ -400,9 +400,10 @@
// segment.
//
// On most targets, this accessor function is __tls_get_addr and
-// TLS_GET_ADDR_CCONV is unset. 32-bit x86 uses ___tls_get_addr instead and a
-// regparm() calling convention.
-extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CCONV {
+// TLS_GET_ADDR_CALLING_CONVENTION is unset, but 32-bit x86 uses
+// ___tls_get_addr (with three underscores) instead, and a regparm
+// calling convention.
+extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CALLING_CONVENTION {
TlsDtv* dtv = __get_tcb_dtv(__get_bionic_tcb());
// TODO: See if we can use a relaxed memory ordering here instead.
diff --git a/libc/bionic/execinfo.cpp b/libc/bionic/execinfo.cpp
index d129f7c..e53a037 100644
--- a/libc/bionic/execinfo.cpp
+++ b/libc/bionic/execinfo.cpp
@@ -73,6 +73,11 @@
#elif defined(__aarch64__)
// All instructions are 4 bytes long, skip back one instruction.
ip -= 4;
+#elif defined(__riscv)
+ // C instructions are the shortest at 2 bytes long. (Unlike thumb, it's
+ // non-trivial to recognize C instructions when going backwards in the
+ // instruction stream.)
+ ip -= 2;
#elif defined(__i386__) || defined(__x86_64__)
// It's difficult to decode exactly where the previous instruction is,
// so subtract 1 to estimate where the instruction lives.
diff --git a/libc/bionic/getpagesize.cpp b/libc/bionic/getpagesize.cpp
index da97633..fbcabd8 100644
--- a/libc/bionic/getpagesize.cpp
+++ b/libc/bionic/getpagesize.cpp
@@ -29,7 +29,6 @@
#include <unistd.h>
#include "platform/bionic/page.h"
-// Portable code should use sysconf(_SC_PAGE_SIZE) directly instead.
int getpagesize() {
// We dont use sysconf(3) here because that drags in stdio, which makes static binaries fat.
return page_size();
diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp
index c8a025f..cadab3c 100644
--- a/libc/bionic/heap_tagging.cpp
+++ b/libc/bionic/heap_tagging.cpp
@@ -34,6 +34,7 @@
#include <platform/bionic/malloc.h>
#include <sanitizer/hwasan_interface.h>
#include <sys/auxv.h>
+#include <sys/prctl.h>
extern "C" void scudo_malloc_disable_memory_tagging();
extern "C" void scudo_malloc_set_track_allocation_stacks(int);
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 41108e6..314fe9b 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -30,24 +30,28 @@
#include <errno.h>
#include <fcntl.h>
-#include <stdarg.h>
+#include <stdint.h>
+#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/vfs.h>
#include <unistd.h>
+#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
+#include "private/ErrnoRestorer.h"
#include "private/bionic_fdtrack.h"
#if defined(__LP64__)
#error This code is only needed on 32-bit systems!
#endif
-// System calls we need.
+// To implement lseek64() on ILP32, we need to use the _llseek() system call
+// which splits the off64_t into two 32-bit arguments and returns the off64_t
+// result via a pointer because 32-bit kernels can't accept 64-bit arguments
+// or return 64-bit results. (Our symbol is __llseek with two underscores for
+// historical reasons, but it's exposed as ABI so we can't fix it.)
extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int);
-// For lseek64 we need to use the llseek system call which splits the off64_t in two and
-// returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results.
off64_t lseek64(int fd, off64_t off, int whence) {
off64_t result;
unsigned long off_hi = static_cast<unsigned long>(off >> 32);
@@ -101,3 +105,33 @@
}
return result;
}
+
+// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks (regardless
+// of page size), not bytes, to enable mapping parts of large files past the
+// 4GiB limit but without the inconvenience of dealing with 64-bit values, with
+// no down side since mappings need to be page aligned anyway, and the 32-bit
+// architectures that support this system call all have 4KiB pages.
+extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
+
+void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
+ static constexpr size_t MMAP2_SHIFT = 12;
+
+ if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT) - 1)) != 0) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ // Prevent allocations large enough for `end - start` to overflow,
+ // to avoid security bugs.
+ size_t rounded = __BIONIC_ALIGN(size, page_size());
+ if (rounded < size || rounded > PTRDIFF_MAX) {
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+
+ return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
+}
+
+void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
+ return mmap64(addr, size, prot, flags, fd, static_cast<off64_t>(offset));
+}
diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp
index deb63f4..5128a35 100644
--- a/libc/bionic/malloc_limit.cpp
+++ b/libc/bionic/malloc_limit.cpp
@@ -31,6 +31,7 @@
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
+#include <unistd.h>
#include <private/bionic_malloc_dispatch.h>
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
deleted file mode 100644
index f05dcb8..0000000
--- a/libc/bionic/mmap.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 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 <errno.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "platform/bionic/macros.h"
-#include "platform/bionic/page.h"
-#include "private/ErrnoRestorer.h"
-
-// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
-extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
-
-#define MMAP2_SHIFT 12 // 2**12 == 4096
-
-void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
- if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
- errno = EINVAL;
- return MAP_FAILED;
- }
-
- // Prevent allocations large enough for `end - start` to overflow.
- size_t rounded = __BIONIC_ALIGN(size, page_size());
- if (rounded < size || rounded > PTRDIFF_MAX) {
- errno = ENOMEM;
- return MAP_FAILED;
- }
-
- return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
-}
-
-void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
- return mmap64(addr, size, prot, flags, fd, static_cast<off64_t>(offset));
-}
diff --git a/libc/bionic/new.cpp b/libc/bionic/new.cpp
index c9ce163..5a6acc0 100644
--- a/libc/bionic/new.cpp
+++ b/libc/bionic/new.cpp
@@ -16,13 +16,14 @@
#include <new>
-#include <errno.h>
#include <stdlib.h>
#include <async_safe/log.h>
__attribute__((weak)) const std::nothrow_t std::nothrow = {};
+// We can't throw in bionic, so we go straight to the equivalent of
+// std::terminate for these two instead.
void* operator new(std::size_t size) {
void* p = malloc(size);
if (p == nullptr) {
@@ -30,7 +31,6 @@
}
return p;
}
-
void* operator new[](std::size_t size) {
void* p = malloc(size);
if (p == nullptr) {
@@ -39,26 +39,21 @@
return p;
}
-void operator delete(void* ptr) throw() {
- free(ptr);
-}
-
-void operator delete[](void* ptr) throw() {
- free(ptr);
-}
-
+// These two are the "nothrow" variants, so we just return nullptr on failure.
void* operator new(std::size_t size, const std::nothrow_t&) {
return malloc(size);
}
-
void* operator new[](std::size_t size, const std::nothrow_t&) {
return malloc(size);
}
-void operator delete(void* ptr, const std::nothrow_t&) throw() {
- free(ptr);
-}
+// free() can't throw anyway (except on heap corruption, which is always fatal),
+// so there's no difference between the regular and "nothrow" variants here.
+void operator delete(void* p) noexcept { free(p); }
+void operator delete[](void* p) noexcept { free(p); }
+void operator delete(void* p, const std::nothrow_t&) noexcept { free(p); }
+void operator delete[](void* p, const std::nothrow_t&) noexcept { free(p); }
-void operator delete[](void* ptr, const std::nothrow_t&) throw() {
- free(ptr);
-}
+// TODO: these can use free_sized() once we have it (http://b/284321795).
+void operator delete(void* p, std::size_t) noexcept { free(p); }
+void operator delete[](void* p, std::size_t) noexcept { free(p); }
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index f522516..ccbbfcf 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -34,6 +34,8 @@
#include <string.h>
#include <time.h>
+#include "private/bionic_lock.h"
+
// System calls.
extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
extern "C" int __rt_sigtimedwait(const sigset64_t*, siginfo_t*, const timespec*, size_t);
@@ -60,6 +62,7 @@
int sigev_notify;
// The fields below are only needed for a SIGEV_THREAD timer.
+ Lock startup_handshake_lock;
pthread_t callback_thread;
void (*callback)(sigval_t);
sigval_t callback_argument;
@@ -73,6 +76,18 @@
static void* __timer_thread_start(void* arg) {
PosixTimer* timer = reinterpret_cast<PosixTimer*>(arg);
+ // Check that our parent managed to create the kernel timer and bail if not...
+ timer->startup_handshake_lock.lock();
+ if (timer->kernel_timer_id == -1) {
+ free(timer);
+ return nullptr;
+ }
+
+ // Give ourselves a specific meaningful name now we have a kernel timer.
+ char name[16]; // 16 is the kernel-imposed limit.
+ snprintf(name, sizeof(name), "POSIX timer %d", to_kernel_timer_id(timer));
+ pthread_setname_np(timer->callback_thread, name);
+
sigset64_t sigset = {};
sigaddset64(&sigset, TIMER_SIGNAL);
@@ -109,6 +124,7 @@
return -1;
}
+ timer->kernel_timer_id = -1;
timer->sigev_notify = (evp == nullptr) ? SIGEV_SIGNAL : evp->sigev_notify;
// If not a SIGEV_THREAD timer, the kernel can handle it without our help.
@@ -149,6 +165,10 @@
sigaddset64(&sigset, TIMER_SIGNAL);
sigset64_t old_sigset;
+ // Prevent the child thread from running until the timer has been created.
+ timer->startup_handshake_lock.init(false);
+ timer->startup_handshake_lock.lock();
+
// Use __rt_sigprocmask instead of sigprocmask64 to avoid filtering out TIMER_SIGNAL.
__rt_sigprocmask(SIG_BLOCK, &sigset, &old_sigset, sizeof(sigset));
@@ -162,21 +182,21 @@
return -1;
}
+ // Try to create the kernel timer.
sigevent se = *evp;
se.sigev_signo = TIMER_SIGNAL;
se.sigev_notify = SIGEV_THREAD_ID;
se.sigev_notify_thread_id = pthread_gettid_np(timer->callback_thread);
- if (__timer_create(clock_id, &se, &timer->kernel_timer_id) == -1) {
- __timer_thread_stop(timer);
+ rc = __timer_create(clock_id, &se, &timer->kernel_timer_id);
+
+ // Let the child run (whether we created the kernel timer or not).
+ timer->startup_handshake_lock.unlock();
+ // If __timer_create(2) failed, the child will kill itself and free the
+ // timer struct, so we just need to exit.
+ if (rc == -1) {
return -1;
}
- // Give the thread a specific meaningful name.
- // It can't do this itself because the kernel timer isn't created until after it's running.
- char name[16]; // 16 is the kernel-imposed limit.
- snprintf(name, sizeof(name), "POSIX timer %d", to_kernel_timer_id(timer));
- pthread_setname_np(timer->callback_thread, name);
-
*timer_id = timer;
return 0;
}
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index f584b27..0181aba 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -133,20 +133,17 @@
// pthread_internal_t is freed below with stack, not here.
__pthread_internal_remove(thread);
-
- if (thread->mmap_size != 0) {
- // We need to free mapped space for detached threads when they exit.
- // That's not something we can do in C.
- __notify_thread_exit_callbacks();
- __hwasan_thread_exit();
- _exit_with_stack_teardown(thread->mmap_base, thread->mmap_size);
- }
}
- // No need to free mapped space. Either there was no space mapped, or it is left for
- // the pthread_join caller to clean up.
__notify_thread_exit_callbacks();
__hwasan_thread_exit();
+ if (old_state == THREAD_DETACHED && thread->mmap_size != 0) {
+ // We need to free mapped space for detached threads when they exit.
+ // That's not something we can do in C.
+ _exit_with_stack_teardown(thread->mmap_base, thread->mmap_size);
+ }
+ // No need to free mapped space. Either there was no space mapped,
+ // or it is left for the pthread_join caller to clean up.
__exit(0);
}
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 091f711..c2abdea 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -240,7 +240,7 @@
// On LP64, we could use more but there's no obvious advantage to doing
// so, and the various media processes use RLIMIT_AS as a way to limit
// the amount of allocation they'll do.
-#define PTHREAD_GUARD_SIZE max_page_size()
+#define PTHREAD_GUARD_SIZE max_android_page_size()
// SIGSTKSZ (8KiB) is not big enough.
// An snprintf to a stack buffer of size PATH_MAX consumes ~7KiB of stack.
diff --git a/libc/bionic/sys_statvfs.cpp b/libc/bionic/sys_statvfs.cpp
index b3a0aca..3a05c3f 100644
--- a/libc/bionic/sys_statvfs.cpp
+++ b/libc/bionic/sys_statvfs.cpp
@@ -17,7 +17,7 @@
#include <sys/statfs.h>
#include <sys/statvfs.h>
-static __inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) {
+static inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) {
dst->f_bsize = src->f_bsize;
dst->f_frsize = src->f_frsize;
dst->f_blocks = src->f_blocks;
diff --git a/libc/bionic/sys_thread_properties.cpp b/libc/bionic/sys_thread_properties.cpp
index d1a73b7..064bca1 100644
--- a/libc/bionic/sys_thread_properties.cpp
+++ b/libc/bionic/sys_thread_properties.cpp
@@ -61,7 +61,7 @@
if (modules.first_thread_exit_callback == nullptr) {
modules.first_thread_exit_callback = cb;
return;
- };
+ }
BionicAllocator& allocator = __libc_shared_globals()->tls_allocator;
CallbackHolder* new_node =
@@ -77,35 +77,9 @@
// Find the thread-pointer register for the given thread.
void** tp_reg = nullptr;
-#if defined(__x86_64__)
- {
- ErrnoRestorer errno_restorer;
- errno = 0;
- uintptr_t fs_base = ptrace(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr);
- if (errno == 0) {
- tp_reg = reinterpret_cast<void**>(fs_base);
- }
- }
-#elif defined(__i386__)
- struct user_regs_struct regs;
- struct iovec pt_iov = {
- .iov_base = ®s,
- .iov_len = sizeof(regs),
- };
-
- if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
- struct user_desc u_info;
- u_info.entry_number = regs.xgs >> 3;
- if (ptrace(PTRACE_GET_THREAD_AREA, tid, u_info.entry_number, &u_info) == 0) {
- tp_reg = reinterpret_cast<void**>(u_info.base_addr);
- }
- }
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
uint64_t reg;
- struct iovec pt_iov {
- .iov_base = ®, .iov_len = sizeof(reg),
- };
-
+ struct iovec pt_iov { .iov_base = ®, .iov_len = sizeof(reg) };
if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TLS, &pt_iov) == 0) {
tp_reg = reinterpret_cast<void**>(reg);
}
@@ -114,6 +88,31 @@
// Reset the tp_reg if ptrace was unsuccessful.
tp_reg = nullptr;
}
+#elif defined(__i386__)
+ struct user_regs_struct regs;
+ struct iovec pt_iov = { .iov_base = ®s, .iov_len = sizeof(regs) };
+ if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
+ struct user_desc u_info;
+ u_info.entry_number = regs.xgs >> 3;
+ if (ptrace(PTRACE_GET_THREAD_AREA, tid, u_info.entry_number, &u_info) == 0) {
+ tp_reg = reinterpret_cast<void**>(u_info.base_addr);
+ }
+ }
+#elif defined(__riscv)
+ struct user_regs_struct regs;
+ struct iovec pt_iov = { .iov_base = ®s, .iov_len = sizeof(regs) };
+ if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) == 0) {
+ tp_reg = reinterpret_cast<void**>(regs.tp);
+ }
+#elif defined(__x86_64__)
+ {
+ ErrnoRestorer errno_restorer;
+ errno = 0;
+ uintptr_t fs_base = ptrace(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr);
+ if (errno == 0) {
+ tp_reg = reinterpret_cast<void**>(fs_base);
+ }
+ }
#endif
if (tp_reg == nullptr) {
diff --git a/libc/bionic/wcwidth.cpp b/libc/bionic/wcwidth.cpp
index 9676b5a..4582ef7 100644
--- a/libc/bionic/wcwidth.cpp
+++ b/libc/bionic/wcwidth.cpp
@@ -52,12 +52,15 @@
return -1;
case U_NON_SPACING_MARK:
case U_ENCLOSING_MARK:
- case U_FORMAT_CHAR:
return 0;
+ case U_FORMAT_CHAR:
+ // A special case for soft hyphen (U+00AD) to match historical practice.
+ // See the tests for more commentary.
+ return (wc == 0x00ad) ? 1 : 0;
}
- if (__icu_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT, nullptr)) return 0;
- // Medial and final jamo render as zero width when used correctly.
+ // Medial and final jamo render as zero width when used correctly,
+ // so we handle them specially rather than relying on East Asian Width.
switch (__icu_getIntPropertyValue(wc, UCHAR_HANGUL_SYLLABLE_TYPE)) {
case U_HST_VOWEL_JAMO:
case U_HST_TRAILING_JAMO:
@@ -68,6 +71,11 @@
return 2;
}
+ // Hangeul choseong filler U+115F is default ignorable, so we check default
+ // ignorability only after we've already handled Hangeul jamo above.
+ if (__icu_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT, nullptr)) return 0;
+
+ // A few weird special cases where EastAsianWidth is not helpful for us.
if (wc >= 0x3248 && wc <= 0x4dff) {
// Circled two-digit CJK "speed sign" numbers. EastAsianWidth is ambiguous,
// but wide makes more sense.
@@ -77,6 +85,7 @@
}
// The EastAsianWidth property is at least defined by the Unicode standard!
+ // https://www.unicode.org/reports/tr11/
switch (__icu_getIntPropertyValue(wc, UCHAR_EAST_ASIAN_WIDTH)) {
case U_EA_AMBIGUOUS:
case U_EA_HALFWIDTH:
diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h
index 5878e0a..459866e 100644
--- a/libc/include/bits/threads_inlines.h
+++ b/libc/include/bits/threads_inlines.h
@@ -124,7 +124,7 @@
};
#pragma clang diagnostic pop
-static inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
+static __inline void* _Nonnull __bionic_thrd_trampoline(void* _Nonnull __arg) {
struct __bionic_thrd_data __data =
*__BIONIC_CAST(static_cast, struct __bionic_thrd_data*, __arg);
free(__arg);
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index ef1e27d..3ebc1be 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -110,7 +110,7 @@
* [malloc_usable_size(3)](http://man7.org/linux/man-pages/man3/malloc_usable_size.3.html)
* returns the actual size of the given heap block.
*/
-size_t malloc_usable_size(const void* _Nullable __ptr);
+size_t malloc_usable_size(const void* _Nullable __ptr) __wur;
#define __MALLINFO_BODY \
/** Total number of non-mmapped bytes currently allocated from OS. */ \
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 78114c3..279c658 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -105,10 +105,10 @@
void clearerr(FILE* _Nonnull __fp);
int fclose(FILE* _Nonnull __fp);
-int feof(FILE* _Nonnull __fp);
-int ferror(FILE* _Nonnull __fp);
+__wur int feof(FILE* _Nonnull __fp);
+__wur int ferror(FILE* _Nonnull __fp);
int fflush(FILE* _Nullable __fp);
-int fgetc(FILE* _Nonnull __fp);
+__wur int fgetc(FILE* _Nonnull __fp);
char* _Nullable fgets(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
int fprintf(FILE* _Nonnull __fp , const char* _Nonnull __fmt, ...) __printflike(2, 3);
int fputc(int __ch, FILE* _Nonnull __fp);
@@ -116,8 +116,8 @@
size_t fread(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
int fscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
size_t fwrite(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
-int getc(FILE* _Nonnull __fp);
-int getchar(void);
+__wur int getc(FILE* _Nonnull __fp);
+__wur int getchar(void);
ssize_t getdelim(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, int __delimiter, FILE* _Nonnull __fp);
ssize_t getline(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, FILE* _Nonnull __fp);
@@ -201,17 +201,17 @@
#endif
int fseek(FILE* _Nonnull __fp, long __offset, int __whence);
-long ftell(FILE* _Nonnull __fp);
+__wur long ftell(FILE* _Nonnull __fp);
/* See https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md */
#if defined(__USE_FILE_OFFSET64)
int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
-off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
+__wur off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
# if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-FILE* _Nullable funopen(const void* _Nullable __cookie,
+__wur FILE* _Nullable funopen(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
@@ -221,10 +221,10 @@
int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos);
int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos);
int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence);
-off_t ftello(FILE* _Nonnull __fp);
+__wur off_t ftello(FILE* _Nonnull __fp);
# if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-FILE* _Nullable funopen(const void* _Nullable __cookie,
+__wur FILE* _Nullable funopen(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
@@ -234,22 +234,22 @@
int fgetpos64(FILE* _Nonnull __fp, fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
int fsetpos64(FILE* _Nonnull __fp, const fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
int fseeko64(FILE* _Nonnull __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
-off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+__wur off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#if defined(__USE_BSD)
/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
-FILE* _Nullable funopen64(const void* _Nullable __cookie,
+__wur FILE* _Nullable funopen64(const void* _Nullable __cookie,
int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
fpos64_t (* _Nullable __seek_fn)(void* _Nonnull, fpos64_t, int),
int (* _Nullable __close_fn)(void* _Nonnull)) __INTRODUCED_IN(24);
#endif
-FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
-FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
+__wur FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
+__wur FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
FILE* _Nullable freopen(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp);
FILE* _Nullable freopen64(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp) __INTRODUCED_IN(24);
-FILE* _Nullable tmpfile(void);
-FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
+__wur FILE* _Nullable tmpfile(void);
+__wur FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
int snprintf(char* __BIONIC_COMPLICATED_NULLNESS __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
int vfscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
@@ -260,20 +260,20 @@
#define L_ctermid 1024 /* size for ctermid() */
char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26);
-FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
-int fileno(FILE* _Nonnull __fp);
+__wur FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
+__wur int fileno(FILE* _Nonnull __fp);
int pclose(FILE* _Nonnull __fp);
-FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
+__wur FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
void flockfile(FILE* _Nonnull __fp);
int ftrylockfile(FILE* _Nonnull __fp);
void funlockfile(FILE* _Nonnull __fp);
-int getc_unlocked(FILE* _Nonnull __fp);
-int getchar_unlocked(void);
+__wur int getc_unlocked(FILE* _Nonnull __fp);
+__wur int getchar_unlocked(void);
int putc_unlocked(int __ch, FILE* _Nonnull __fp);
int putchar_unlocked(int __ch);
-FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
-FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
+__wur FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
+__wur FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
int asprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, ...) __printflike(2, 3);
@@ -283,16 +283,16 @@
int setlinebuf(FILE* _Nonnull __fp);
int vasprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
void clearerr_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
-int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+__wur int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+__wur int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+__wur int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif
#if defined(__USE_BSD)
int fflush_unlocked(FILE* _Nullable __fp) __INTRODUCED_IN(28);
-int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+__wur int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
int fputc_unlocked(int __ch, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
size_t fread_unlocked(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
size_t fwrite_unlocked(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 506ab43..d0efc4c 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -105,7 +105,14 @@
*/
int system(const char* _Nonnull __command);
-void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
+/**
+ * [bsearch(3)](http://man7.org/linux/man-pages/man3/bsearch.3.html) searches
+ * a sorted array.
+ *
+ * Returns a pointer to a matching item on success,
+ * or NULL if no matching item is found.
+ */
+__wur void* _Nullable bsearch(const void* _Nonnull __key, const void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull __lhs, const void* _Nonnull __rhs));
void qsort(void* _Nullable __base, size_t __nmemb, size_t __size, int (* _Nonnull __comparator)(const void* _Nullable __lhs, const void* _Nullable __rhs));
diff --git a/libc/include/strings.h b/libc/include/strings.h
index 2f4f764..4b8cc08 100644
--- a/libc/include/strings.h
+++ b/libc/include/strings.h
@@ -61,13 +61,13 @@
/** Deprecated. Use memmove() instead. */
#define bcopy(b1, b2, len) __bionic_bcopy((b1), (b2), (len))
-static __inline__ __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) {
+static __inline __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) {
__builtin_memmove(b2, b1, len);
}
/** Deprecated. Use memset() instead. */
#define bzero(b, len) __bionic_bzero((b), (len))
-static __inline__ __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) {
+static __inline __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) {
__builtin_memset(b, 0, len);
}
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 7625d38..5d1718e 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -87,9 +87,12 @@
#define __STRING(x) #x
#define ___STRING(x) __STRING(x)
-#if defined(__cplusplus)
-#define __inline inline /* convert to C++ keyword */
-#endif /* !__cplusplus */
+// C++ has `inline` as a keyword, as does C99, but ANSI C (aka C89 aka C90)
+// does not. Everything accepts the `__inline__` extension though. We could
+// just use that directly in our own code, but there's historical precedent
+// for `__inline` meaning it's still used in upstream BSD code (and potentially
+// downstream in vendor or app code).
+#define __inline __inline__
#define __always_inline __attribute__((__always_inline__))
#define __attribute_const__ __attribute__((__const__))
@@ -260,7 +263,7 @@
* them available externally. FORTIFY'ed functions try to be as close to possible as 'invisible';
* having stack protectors detracts from that (b/182948263).
*/
-# define __BIONIC_FORTIFY_INLINE static __inline__ __attribute__((__no_stack_protector__)) \
+# define __BIONIC_FORTIFY_INLINE static __inline __attribute__((__no_stack_protector__)) \
__always_inline __VERSIONER_FORTIFY_INLINE
/*
* We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE
@@ -268,9 +271,9 @@
* The __always_inline attribute is useless, misleading, and could trigger
* clang compiler bug to incorrectly inline variadic functions.
*/
-# define __BIONIC_FORTIFY_VARIADIC static __inline__
+# define __BIONIC_FORTIFY_VARIADIC static __inline
/* Error functions don't have bodies, so they can just be static. */
-# define __BIONIC_ERROR_FUNCTION_VISIBILITY static __attribute__((__unused__))
+# define __BIONIC_ERROR_FUNCTION_VISIBILITY static __unused
#else
/* Further increase sharing for some inline functions */
# define __pass_object_size_n(n)
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index 2732214..2552ca8 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -113,8 +113,22 @@
*/
pid_t vfork(void) __returns_twice;
+/**
+ * [getpid(2)](http://man7.org/linux/man-pages/man2/getpid.2.html) returns
+ * the caller's process ID.
+ *
+ * Returns the caller's process ID.
+ */
pid_t getpid(void);
-pid_t gettid(void) __attribute_const__;
+
+/**
+ * [gettid(2)](http://man7.org/linux/man-pages/man2/gettid.2.html) returns
+ * the caller's thread ID.
+ *
+ * Returns the caller's thread ID.
+ */
+pid_t gettid(void);
+
pid_t getpgid(pid_t __pid);
int setpgid(pid_t __pid, pid_t __pgid);
pid_t getppid(void);
@@ -339,7 +353,7 @@
/**
* [getpagesize(2)](https://man7.org/linux/man-pages/man2/getpagesize.2.html)
* returns the system's page size. This is slightly faster than going via
- * sysconf().
+ * sysconf(), and avoids the linear search in getauxval().
*
* Returns the system's page size in bytes.
*/
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 5abff63..f5c720a 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -86,4 +86,19 @@
#define HWCAP2_SVE_B16B16 (1UL << 45)
#define HWCAP2_LRCPC3 (1UL << 46)
#define HWCAP2_LSE128 (1UL << 47)
+#define HWCAP2_FPMR (1UL << 48)
+#define HWCAP2_LUT (1UL << 49)
+#define HWCAP2_FAMINMAX (1UL << 50)
+#define HWCAP2_F8CVT (1UL << 51)
+#define HWCAP2_F8FMA (1UL << 52)
+#define HWCAP2_F8DP4 (1UL << 53)
+#define HWCAP2_F8DP2 (1UL << 54)
+#define HWCAP2_F8E4M3 (1UL << 55)
+#define HWCAP2_F8E5M2 (1UL << 56)
+#define HWCAP2_SME_LUTV2 (1UL << 57)
+#define HWCAP2_SME_F8F16 (1UL << 58)
+#define HWCAP2_SME_F8F32 (1UL << 59)
+#define HWCAP2_SME_SF8FMA (1UL << 60)
+#define HWCAP2_SME_SF8DP4 (1UL << 61)
+#define HWCAP2_SME_SF8DP2 (1UL << 62)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index 5ad9021..1818c5f 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -18,9 +18,7 @@
#include <linux/types.h>
#include <asm/ptrace.h>
#include <asm/sve_context.h>
-#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_READONLY_MEM
#define __KVM_HAVE_VCPU_EVENTS
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
@@ -40,9 +38,9 @@
#define KVM_ARM_TARGET_GENERIC_V8 5
#define KVM_ARM_NUM_TARGETS 6
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
-#define KVM_ARM_DEVICE_TYPE_MASK GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_TYPE_MASK __GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, KVM_ARM_DEVICE_TYPE_SHIFT)
#define KVM_ARM_DEVICE_ID_SHIFT 16
-#define KVM_ARM_DEVICE_ID_MASK GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, KVM_ARM_DEVICE_ID_SHIFT)
+#define KVM_ARM_DEVICE_ID_MASK __GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, KVM_ARM_DEVICE_ID_SHIFT)
#define KVM_ARM_DEVICE_VGIC_V2 0
#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
#define KVM_VGIC_V2_ADDR_TYPE_CPU 1
@@ -89,6 +87,9 @@
struct kvm_sync_regs {
__u64 device_irq_level;
};
+#define KVM_ARM_DEV_EL1_VTIMER (1 << 0)
+#define KVM_ARM_DEV_EL1_PTIMER (1 << 1)
+#define KVM_ARM_DEV_PMU (1 << 2)
struct kvm_pmu_event_filter {
__u16 base_event;
__u16 nevents;
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 6098fc7..8e48d55 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -52,6 +52,11 @@
struct _aarch64_ctx head;
__u64 tpidr2;
};
+#define FPMR_MAGIC 0x46504d52
+struct fpmr_context {
+ struct _aarch64_ctx head;
+ __u64 fpmr;
+};
#define ZA_MAGIC 0x54366345
struct za_context {
struct _aarch64_ctx head;
diff --git a/libc/kernel/uapi/asm-generic/bitsperlong.h b/libc/kernel/uapi/asm-generic/bitsperlong.h
index 969913b..11dcc1a 100644
--- a/libc/kernel/uapi/asm-generic/bitsperlong.h
+++ b/libc/kernel/uapi/asm-generic/bitsperlong.h
@@ -13,4 +13,7 @@
#define __BITS_PER_LONG 32
#endif
#endif
+#ifndef __BITS_PER_LONG_LONG
+#define __BITS_PER_LONG_LONG 64
+#endif
#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/auxvec.h b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
index 446fc54..755f4e9 100644
--- a/libc/kernel/uapi/asm-riscv/asm/auxvec.h
+++ b/libc/kernel/uapi/asm-riscv/asm/auxvec.h
@@ -15,6 +15,6 @@
#define AT_L2_CACHEGEOMETRY 45
#define AT_L3_CACHESIZE 46
#define AT_L3_CACHEGEOMETRY 47
-#define AT_VECTOR_SIZE_ARCH 9
+#define AT_VECTOR_SIZE_ARCH 10
#define AT_MINSIGSTKSZ 51
#endif
diff --git a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
index 6f8d8f5..5c82561 100644
--- a/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
+++ b/libc/kernel/uapi/asm-riscv/asm/hwprobe.h
@@ -48,7 +48,7 @@
#define RISCV_HWPROBE_EXT_ZFHMIN (1 << 28)
#define RISCV_HWPROBE_EXT_ZIHINTNTL (1 << 29)
#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
-#define RISCV_HWPROBE_EXT_ZVFHMIN (1 << 31)
+#define RISCV_HWPROBE_EXT_ZVFHMIN (1ULL << 31)
#define RISCV_HWPROBE_EXT_ZFA (1ULL << 32)
#define RISCV_HWPROBE_EXT_ZTSO (1ULL << 33)
#define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
diff --git a/libc/kernel/uapi/asm-riscv/asm/kvm.h b/libc/kernel/uapi/asm-riscv/asm/kvm.h
index 054e1a1..4c759ed 100644
--- a/libc/kernel/uapi/asm-riscv/asm/kvm.h
+++ b/libc/kernel/uapi/asm-riscv/asm/kvm.h
@@ -11,7 +11,6 @@
#include <asm/bitsperlong.h>
#include <asm/ptrace.h>
#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_READONLY_MEM
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_INTERRUPT_SET - 1U
#define KVM_INTERRUPT_UNSET - 2U
@@ -126,6 +125,8 @@
KVM_RISCV_ISA_EXT_ZVFH,
KVM_RISCV_ISA_EXT_ZVFHMIN,
KVM_RISCV_ISA_EXT_ZFA,
+ KVM_RISCV_ISA_EXT_ZTSO,
+ KVM_RISCV_ISA_EXT_ZACAS,
KVM_RISCV_ISA_EXT_MAX,
};
enum KVM_RISCV_SBI_EXT_ID {
diff --git a/libc/kernel/uapi/asm-x86/asm/bootparam.h b/libc/kernel/uapi/asm-x86/asm/bootparam.h
index c87a8af..6a4b59c 100644
--- a/libc/kernel/uapi/asm-x86/asm/bootparam.h
+++ b/libc/kernel/uapi/asm-x86/asm/bootparam.h
@@ -6,19 +6,7 @@
*/
#ifndef _ASM_X86_BOOTPARAM_H
#define _ASM_X86_BOOTPARAM_H
-#define SETUP_NONE 0
-#define SETUP_E820_EXT 1
-#define SETUP_DTB 2
-#define SETUP_PCI 3
-#define SETUP_EFI 4
-#define SETUP_APPLE_PROPERTIES 5
-#define SETUP_JAILHOUSE 6
-#define SETUP_CC_BLOB 7
-#define SETUP_IMA 8
-#define SETUP_RNG_SEED 9
-#define SETUP_ENUM_MAX SETUP_RNG_SEED
-#define SETUP_INDIRECT (1 << 31)
-#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
+#include <asm/setup_data.h>
#define RAMDISK_IMAGE_START_MASK 0x07FF
#define RAMDISK_PROMPT_FLAG 0x8000
#define RAMDISK_LOAD_FLAG 0x4000
@@ -34,6 +22,7 @@
#define XLF_EFI_KEXEC (1 << 4)
#define XLF_5LEVEL (1 << 5)
#define XLF_5LEVEL_ENABLED (1 << 6)
+#define XLF_MEM_ENCRYPTION (1 << 7)
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <linux/screen_info.h>
@@ -41,18 +30,6 @@
#include <linux/edd.h>
#include <asm/ist.h>
#include <video/edid.h>
-struct setup_data {
- __u64 next;
- __u32 type;
- __u32 len;
- __u8 data[];
-};
-struct setup_indirect {
- __u32 type;
- __u32 reserved;
- __u64 len;
- __u64 addr;
-};
struct setup_header {
__u8 setup_sects;
__u16 root_flags;
@@ -115,34 +92,7 @@
__u32 efi_memmap_hi;
};
#define E820_MAX_ENTRIES_ZEROPAGE 128
-struct boot_e820_entry {
- __u64 addr;
- __u64 size;
- __u32 type;
-} __attribute__((packed));
#define JAILHOUSE_SETUP_REQUIRED_VERSION 1
-struct jailhouse_setup_data {
- struct {
- __u16 version;
- __u16 compatible_version;
- } __attribute__((packed)) hdr;
- struct {
- __u16 pm_timer_address;
- __u16 num_cpus;
- __u64 pci_mmconfig_base;
- __u32 tsc_khz;
- __u32 apic_khz;
- __u8 standard_ioapic;
- __u8 cpu_ids[255];
- } __attribute__((packed)) v1;
- struct {
- __u32 flags;
- } __attribute__((packed)) v2;
-} __attribute__((packed));
-struct ima_setup_data {
- __u64 addr;
- __u64 size;
-} __attribute__((packed));
struct boot_params {
struct screen_info screen_info;
struct apm_bios_info apm_bios_info;
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm.h b/libc/kernel/uapi/asm-x86/asm/kvm.h
index 1dd057a..440ffb8 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm.h
@@ -6,6 +6,8 @@
*/
#ifndef _ASM_X86_KVM_H
#define _ASM_X86_KVM_H
+#include <linux/const.h>
+#include <linux/bits.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/stddef.h>
@@ -35,7 +37,6 @@
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI
-#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_MSIX
#define __KVM_HAVE_MCE
#define __KVM_HAVE_PIT_STATE2
@@ -44,7 +45,6 @@
#define __KVM_HAVE_DEBUGREGS
#define __KVM_HAVE_XSAVE
#define __KVM_HAVE_XCRS
-#define __KVM_HAVE_READONLY_MEM
#define KVM_NR_INTERRUPTS 256
struct kvm_pic_state {
__u8 last_irr;
@@ -398,17 +398,260 @@
};
#define KVM_PMU_EVENT_ALLOW 0
#define KVM_PMU_EVENT_DENY 1
-#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS _BITUL(0)
#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
+struct kvm_x86_mce {
+ __u64 status;
+ __u64 addr;
+ __u64 misc;
+ __u64 mcg_status;
+ __u8 bank;
+ __u8 pad1[7];
+ __u64 pad2[3];
+};
+#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
+#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
+#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
+#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
+#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
+#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
+#define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA (1 << 8)
+struct kvm_xen_hvm_config {
+ __u32 flags;
+ __u32 msr;
+ __u64 blob_addr_32;
+ __u64 blob_addr_64;
+ __u8 blob_size_32;
+ __u8 blob_size_64;
+ __u8 pad2[30];
+};
+struct kvm_xen_hvm_attr {
+ __u16 type;
+ __u16 pad[3];
+ union {
+ __u8 long_mode;
+ __u8 vector;
+ __u8 runstate_update_flag;
+ union {
+ __u64 gfn;
+#define KVM_XEN_INVALID_GFN ((__u64) - 1)
+ __u64 hva;
+ } shared_info;
+ struct {
+ __u32 send_port;
+ __u32 type;
+ __u32 flags;
+#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0)
+#define KVM_XEN_EVTCHN_UPDATE (1 << 1)
+#define KVM_XEN_EVTCHN_RESET (1 << 2)
+ union {
+ struct {
+ __u32 port;
+ __u32 vcpu;
+ __u32 priority;
+ } port;
+ struct {
+ __u32 port;
+ __s32 fd;
+ } eventfd;
+ __u32 padding[4];
+ } deliver;
+ } evtchn;
+ __u32 xen_version;
+ __u64 pad[8];
+ } u;
+};
+#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
+#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
+#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
+#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3
+#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4
+#define KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG 0x5
+#define KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA 0x6
+struct kvm_xen_vcpu_attr {
+ __u16 type;
+ __u16 pad[3];
+ union {
+ __u64 gpa;
+#define KVM_XEN_INVALID_GPA ((__u64) - 1)
+ __u64 hva;
+ __u64 pad[8];
+ struct {
+ __u64 state;
+ __u64 state_entry_time;
+ __u64 time_running;
+ __u64 time_runnable;
+ __u64 time_blocked;
+ __u64 time_offline;
+ } runstate;
+ __u32 vcpu_id;
+ struct {
+ __u32 port;
+ __u32 priority;
+ __u64 expires_ns;
+ } timer;
+ __u8 vector;
+ } u;
+};
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6
+#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7
+#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA 0x9
+enum sev_cmd_id {
+ KVM_SEV_INIT = 0,
+ KVM_SEV_ES_INIT,
+ KVM_SEV_LAUNCH_START,
+ KVM_SEV_LAUNCH_UPDATE_DATA,
+ KVM_SEV_LAUNCH_UPDATE_VMSA,
+ KVM_SEV_LAUNCH_SECRET,
+ KVM_SEV_LAUNCH_MEASURE,
+ KVM_SEV_LAUNCH_FINISH,
+ KVM_SEV_SEND_START,
+ KVM_SEV_SEND_UPDATE_DATA,
+ KVM_SEV_SEND_UPDATE_VMSA,
+ KVM_SEV_SEND_FINISH,
+ KVM_SEV_RECEIVE_START,
+ KVM_SEV_RECEIVE_UPDATE_DATA,
+ KVM_SEV_RECEIVE_UPDATE_VMSA,
+ KVM_SEV_RECEIVE_FINISH,
+ KVM_SEV_GUEST_STATUS,
+ KVM_SEV_DBG_DECRYPT,
+ KVM_SEV_DBG_ENCRYPT,
+ KVM_SEV_CERT_EXPORT,
+ KVM_SEV_GET_ATTESTATION_REPORT,
+ KVM_SEV_SEND_CANCEL,
+ KVM_SEV_NR_MAX,
+};
+struct kvm_sev_cmd {
+ __u32 id;
+ __u32 pad0;
+ __u64 data;
+ __u32 error;
+ __u32 sev_fd;
+};
+struct kvm_sev_launch_start {
+ __u32 handle;
+ __u32 policy;
+ __u64 dh_uaddr;
+ __u32 dh_len;
+ __u32 pad0;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad1;
+};
+struct kvm_sev_launch_update_data {
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+struct kvm_sev_launch_secret {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+struct kvm_sev_launch_measure {
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+struct kvm_sev_guest_status {
+ __u32 handle;
+ __u32 policy;
+ __u32 state;
+};
+struct kvm_sev_dbg {
+ __u64 src_uaddr;
+ __u64 dst_uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+struct kvm_sev_attestation_report {
+ __u8 mnonce[16];
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+struct kvm_sev_send_start {
+ __u32 policy;
+ __u32 pad0;
+ __u64 pdh_cert_uaddr;
+ __u32 pdh_cert_len;
+ __u32 pad1;
+ __u64 plat_certs_uaddr;
+ __u32 plat_certs_len;
+ __u32 pad2;
+ __u64 amd_certs_uaddr;
+ __u32 amd_certs_len;
+ __u32 pad3;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad4;
+};
+struct kvm_sev_send_update_data {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+struct kvm_sev_receive_start {
+ __u32 handle;
+ __u32 policy;
+ __u64 pdh_uaddr;
+ __u32 pdh_len;
+ __u32 pad0;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad1;
+};
+struct kvm_sev_receive_update_data {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
+#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
+struct kvm_hyperv_eventfd {
+ __u32 conn_id;
+ __s32 fd;
+ __u32 flags;
+ __u32 padding[3];
+};
+#define KVM_HYPERV_CONN_ID_MASK 0x00ffffff
+#define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0)
#define KVM_PMU_ENCODE_MASKED_ENTRY(event_select,mask,match,exclude) (((event_select) & 0xFFULL) | (((event_select) & 0XF00ULL) << 24) | (((mask) & 0xFFULL) << 56) | (((match) & 0xFFULL) << 8) | ((__u64) (! ! (exclude)) << 55))
-#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
-#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (GENMASK_ULL(63, 56))
-#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (GENMASK_ULL(15, 8))
-#define KVM_PMU_MASKED_ENTRY_EXCLUDE (BIT_ULL(55))
+#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT (__GENMASK_ULL(7, 0) | __GENMASK_ULL(35, 32))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (__GENMASK_ULL(63, 56))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (__GENMASK_ULL(15, 8))
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE (_BITULL(55))
#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)
+#define KVM_EXIT_HYPERCALL_LONG_MODE _BITULL(0)
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index 03421ed..3395a15 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -67,7 +67,7 @@
#define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
#define KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT (1 << 2)
#define KVM_ASYNC_PF_DELIVERY_AS_INT (1 << 3)
-#define KVM_ASYNC_PF_VEC_MASK GENMASK(7, 0)
+#define KVM_ASYNC_PF_VEC_MASK __GENMASK(7, 0)
#define KVM_MIGRATION_READY (1 << 0)
#define KVM_MAP_GPA_RANGE_PAGE_SZ_4K 0
#define KVM_MAP_GPA_RANGE_PAGE_SZ_2M (1 << 0)
@@ -100,7 +100,6 @@
__u32 flags;
__u32 token;
__u8 pad[56];
- __u32 enabled;
};
#define KVM_PV_EOI_BIT 0
#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT)
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index f06fdda..9842847 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -123,6 +123,12 @@
#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)
+#ifdef __x86_64__
+#define X86_CR4_FRED_BIT 32
+#define X86_CR4_FRED _BITUL(X86_CR4_FRED_BIT)
+#else
+#define X86_CR4_FRED (0)
+#endif
#define X86_CR8_TPR _AC(0x0000000f, UL)
#define CX86_PCR0 0x20
#define CX86_GCR 0xb8
diff --git a/libc/kernel/uapi/asm-x86/asm/setup_data.h b/libc/kernel/uapi/asm-x86/asm/setup_data.h
new file mode 100644
index 0000000..d00a554
--- /dev/null
+++ b/libc/kernel/uapi/asm-x86/asm/setup_data.h
@@ -0,0 +1,64 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_ASM_X86_SETUP_DATA_H
+#define _UAPI_ASM_X86_SETUP_DATA_H
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+#define SETUP_PCI 3
+#define SETUP_EFI 4
+#define SETUP_APPLE_PROPERTIES 5
+#define SETUP_JAILHOUSE 6
+#define SETUP_CC_BLOB 7
+#define SETUP_IMA 8
+#define SETUP_RNG_SEED 9
+#define SETUP_ENUM_MAX SETUP_RNG_SEED
+#define SETUP_INDIRECT (1 << 31)
+#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+struct setup_data {
+ __u64 next;
+ __u32 type;
+ __u32 len;
+ __u8 data[];
+};
+struct setup_indirect {
+ __u32 type;
+ __u32 reserved;
+ __u64 len;
+ __u64 addr;
+};
+struct boot_e820_entry {
+ __u64 addr;
+ __u64 size;
+ __u32 type;
+} __attribute__((packed));
+struct jailhouse_setup_data {
+ struct {
+ __u16 version;
+ __u16 compatible_version;
+ } __attribute__((packed)) hdr;
+ struct {
+ __u16 pm_timer_address;
+ __u16 num_cpus;
+ __u64 pci_mmconfig_base;
+ __u32 tsc_khz;
+ __u32 apic_khz;
+ __u8 standard_ioapic;
+ __u8 cpu_ids[255];
+ } __attribute__((packed)) v1;
+ struct {
+ __u32 flags;
+ } __attribute__((packed)) v2;
+} __attribute__((packed));
+struct ima_setup_data {
+ __u64 addr;
+ __u64 size;
+} __attribute__((packed));
+#endif
+#endif
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index 1e5b8e3..0ad0bc2 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -490,6 +490,7 @@
#define AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK 0x9
#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK 0xa
#define AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK 0xb
+#define AMDGPU_INFO_SENSOR_GPU_INPUT_POWER 0xc
#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
#define AMDGPU_INFO_VRAM_LOST_COUNTER 0x1F
#define AMDGPU_INFO_RAS_ENABLED_FEATURES 0x20
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index ccb8278..0738cee 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -901,6 +901,7 @@
#define DRM_I915_QUERY_MEMORY_REGIONS 4
#define DRM_I915_QUERY_HWCONFIG_BLOB 5
#define DRM_I915_QUERY_GEOMETRY_SUBSLICES 6
+#define DRM_I915_QUERY_GUC_SUBMISSION_VERSION 7
__s32 length;
__u32 flags;
#define DRM_I915_QUERY_PERF_CONFIG_LIST 1
@@ -976,6 +977,12 @@
__u32 rsvd[3];
struct drm_i915_memory_region_info regions[];
};
+struct drm_i915_query_guc_submission_version {
+ __u32 branch;
+ __u32 major;
+ __u32 minor;
+ __u32 patch;
+};
struct drm_i915_gem_create_ext {
__u64 size;
__u32 handle;
diff --git a/libc/kernel/uapi/drm/xe_drm.h b/libc/kernel/uapi/drm/xe_drm.h
index 1e9f128..dd0da6f 100644
--- a/libc/kernel/uapi/drm/xe_drm.h
+++ b/libc/kernel/uapi/drm/xe_drm.h
@@ -129,6 +129,17 @@
__u64 cpu_timestamp;
__u64 cpu_delta;
};
+struct drm_xe_query_uc_fw_version {
+#define XE_QUERY_UC_TYPE_GUC_SUBMISSION 0
+ __u16 uc_type;
+ __u16 pad;
+ __u32 branch_ver;
+ __u32 major_ver;
+ __u32 minor_ver;
+ __u32 patch_ver;
+ __u32 pad2;
+ __u64 reserved;
+};
struct drm_xe_device_query {
__u64 extensions;
#define DRM_XE_DEVICE_QUERY_ENGINES 0
@@ -138,6 +149,7 @@
#define DRM_XE_DEVICE_QUERY_HWCONFIG 4
#define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5
#define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6
+#define DRM_XE_DEVICE_QUERY_UC_FW_VERSION 7
__u32 query;
__u32 size;
__u64 data;
diff --git a/libc/kernel/uapi/linux/auxvec.h b/libc/kernel/uapi/linux/auxvec.h
index ce02287..6dbdc75 100644
--- a/libc/kernel/uapi/linux/auxvec.h
+++ b/libc/kernel/uapi/linux/auxvec.h
@@ -31,6 +31,8 @@
#define AT_HWCAP2 26
#define AT_RSEQ_FEATURE_SIZE 27
#define AT_RSEQ_ALIGN 28
+#define AT_HWCAP3 29
+#define AT_HWCAP4 30
#define AT_EXECFN 31
#ifndef AT_MINSIGSTKSZ
#define AT_MINSIGSTKSZ 51
diff --git a/libc/kernel/uapi/linux/bits.h b/libc/kernel/uapi/linux/bits.h
new file mode 100644
index 0000000..d747e24
--- /dev/null
+++ b/libc/kernel/uapi/linux/bits.h
@@ -0,0 +1,11 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_BITS_H
+#define _UAPI_LINUX_BITS_H
+#define __GENMASK(h,l) (((~_UL(0)) - (_UL(1) << (l)) + 1) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
+#define __GENMASK_ULL(h,l) (((~_ULL(0)) - (_ULL(1) << (l)) + 1) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
+#endif
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 8f82b71..0e9e883 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -28,11 +28,15 @@
#define BPF_JSGE 0x70
#define BPF_JSLT 0xc0
#define BPF_JSLE 0xd0
+#define BPF_JCOND 0xe0
#define BPF_CALL 0x80
#define BPF_EXIT 0x90
#define BPF_FETCH 0x01
#define BPF_XCHG (0xe0 | BPF_FETCH)
#define BPF_CMPXCHG (0xf0 | BPF_FETCH)
+enum bpf_cond_pseudo_jmp {
+ BPF_MAY_GOTO = 0,
+};
enum {
BPF_REG_0 = 0,
BPF_REG_1,
@@ -59,6 +63,16 @@
__u32 prefixlen;
__u8 data[0];
};
+struct bpf_lpm_trie_key_hdr {
+ __u32 prefixlen;
+};
+struct bpf_lpm_trie_key_u8 {
+ union {
+ struct bpf_lpm_trie_key_hdr hdr;
+ __u32 prefixlen;
+ };
+ __u8 data[];
+};
struct bpf_cgroup_storage_key {
__u64 cgroup_inode_id;
__u32 attach_type;
@@ -123,6 +137,8 @@
BPF_ITER_CREATE,
BPF_LINK_DETACH,
BPF_PROG_BIND_MAP,
+ BPF_TOKEN_CREATE,
+ __MAX_BPF_CMD,
};
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
@@ -160,6 +176,8 @@
BPF_MAP_TYPE_BLOOM_FILTER,
BPF_MAP_TYPE_USER_RINGBUF,
BPF_MAP_TYPE_CGRP_STORAGE,
+ BPF_MAP_TYPE_ARENA,
+ __MAX_BPF_MAP_TYPE
};
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC,
@@ -195,6 +213,7 @@
BPF_PROG_TYPE_SK_LOOKUP,
BPF_PROG_TYPE_SYSCALL,
BPF_PROG_TYPE_NETFILTER,
+ __MAX_BPF_PROG_TYPE
};
enum bpf_attach_type {
BPF_CGROUP_INET_INGRESS,
@@ -313,6 +332,9 @@
#define BPF_PSEUDO_FUNC 4
#define BPF_PSEUDO_CALL 1
#define BPF_PSEUDO_KFUNC_CALL 2
+enum bpf_addr_space_cast {
+ BPF_ADDR_SPACE_CAST = 1,
+};
enum {
BPF_ANY = 0,
BPF_NOEXIST = 1,
@@ -335,6 +357,10 @@
BPF_F_INNER_MAP = (1U << 12),
BPF_F_LINK = (1U << 13),
BPF_F_PATH_FD = (1U << 14),
+ BPF_F_VTYPE_BTF_OBJ_FD = (1U << 15),
+ BPF_F_TOKEN_FD = (1U << 16),
+ BPF_F_SEGV_ON_FAULT = (1U << 17),
+ BPF_F_NO_USER_CONV = (1U << 18),
};
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
#define BPF_F_TEST_RUN_ON_CPU (1U << 0)
@@ -373,6 +399,8 @@
__u32 btf_value_type_id;
__u32 btf_vmlinux_value_type_id;
__u64 map_extra;
+ __s32 value_type_btf_obj_fd;
+ __s32 map_token_fd;
};
struct {
__u32 map_fd;
@@ -423,6 +451,7 @@
__aligned_u64 core_relos;
__u32 core_relo_rec_size;
__u32 log_true_size;
+ __s32 prog_token_fd;
};
struct {
__aligned_u64 pathname;
@@ -508,6 +537,8 @@
__u32 btf_log_size;
__u32 btf_log_level;
__u32 btf_log_true_size;
+ __u32 btf_flags;
+ __s32 btf_token_fd;
};
struct {
__u32 pid;
@@ -609,6 +640,10 @@
__u32 map_fd;
__u32 flags;
} prog_bind_map;
+ struct {
+ __u32 flags;
+ __u32 bpffs_fd;
+ } token_create;
} __attribute__((aligned(8)));
#define ___BPF_FUNC_MAPPER(FN,ctx...) FN(unspec, 0, ##ctx) FN(map_lookup_elem, 1, ##ctx) FN(map_update_elem, 2, ##ctx) FN(map_delete_elem, 3, ##ctx) FN(probe_read, 4, ##ctx) FN(ktime_get_ns, 5, ##ctx) FN(trace_printk, 6, ##ctx) FN(get_prandom_u32, 7, ##ctx) FN(get_smp_processor_id, 8, ##ctx) FN(skb_store_bytes, 9, ##ctx) FN(l3_csum_replace, 10, ##ctx) FN(l4_csum_replace, 11, ##ctx) FN(tail_call, 12, ##ctx) FN(clone_redirect, 13, ##ctx) FN(get_current_pid_tgid, 14, ##ctx) FN(get_current_uid_gid, 15, ##ctx) FN(get_current_comm, 16, ##ctx) FN(get_cgroup_classid, 17, ##ctx) FN(skb_vlan_push, 18, ##ctx) FN(skb_vlan_pop, 19, ##ctx) FN(skb_get_tunnel_key, 20, ##ctx) FN(skb_set_tunnel_key, 21, ##ctx) FN(perf_event_read, 22, ##ctx) FN(redirect, 23, ##ctx) FN(get_route_realm, 24, ##ctx) FN(perf_event_output, 25, ##ctx) FN(skb_load_bytes, 26, ##ctx) FN(get_stackid, 27, ##ctx) FN(csum_diff, 28, ##ctx) FN(skb_get_tunnel_opt, 29, ##ctx) FN(skb_set_tunnel_opt, 30, ##ctx) FN(skb_change_proto, 31, ##ctx) FN(skb_change_type, 32, ##ctx) FN(skb_under_cgroup, 33, ##ctx) FN(get_hash_recalc, 34, ##ctx) FN(get_current_task, 35, ##ctx) FN(probe_write_user, 36, ##ctx) FN(current_task_under_cgroup, 37, ##ctx) FN(skb_change_tail, 38, ##ctx) FN(skb_pull_data, 39, ##ctx) FN(csum_update, 40, ##ctx) FN(set_hash_invalid, 41, ##ctx) FN(get_numa_node_id, 42, ##ctx) FN(skb_change_head, 43, ##ctx) FN(xdp_adjust_head, 44, ##ctx) FN(probe_read_str, 45, ##ctx) FN(get_socket_cookie, 46, ##ctx) FN(get_socket_uid, 47, ##ctx) FN(set_hash, 48, ##ctx) FN(setsockopt, 49, ##ctx) FN(skb_adjust_room, 50, ##ctx) FN(redirect_map, 51, ##ctx) FN(sk_redirect_map, 52, ##ctx) FN(sock_map_update, 53, ##ctx) FN(xdp_adjust_meta, 54, ##ctx) FN(perf_event_read_value, 55, ##ctx) FN(perf_prog_read_value, 56, ##ctx) FN(getsockopt, 57, ##ctx) FN(override_return, 58, ##ctx) FN(sock_ops_cb_flags_set, 59, ##ctx) FN(msg_redirect_map, 60, ##ctx) FN(msg_apply_bytes, 61, ##ctx) FN(msg_cork_bytes, 62, ##ctx) FN(msg_pull_data, 63, ##ctx) FN(bind, 64, ##ctx) FN(xdp_adjust_tail, 65, ##ctx) FN(skb_get_xfrm_state, 66, ##ctx) FN(get_stack, 67, ##ctx) FN(skb_load_bytes_relative, 68, ##ctx) FN(fib_lookup, 69, ##ctx) FN(sock_hash_update, 70, ##ctx) FN(msg_redirect_hash, 71, ##ctx) FN(sk_redirect_hash, 72, ##ctx) FN(lwt_push_encap, 73, ##ctx) FN(lwt_seg6_store_bytes, 74, ##ctx) FN(lwt_seg6_adjust_srh, 75, ##ctx) FN(lwt_seg6_action, 76, ##ctx) FN(rc_repeat, 77, ##ctx) FN(rc_keydown, 78, ##ctx) FN(skb_cgroup_id, 79, ##ctx) FN(get_current_cgroup_id, 80, ##ctx) FN(get_local_storage, 81, ##ctx) FN(sk_select_reuseport, 82, ##ctx) FN(skb_ancestor_cgroup_id, 83, ##ctx) FN(sk_lookup_tcp, 84, ##ctx) FN(sk_lookup_udp, 85, ##ctx) FN(sk_release, 86, ##ctx) FN(map_push_elem, 87, ##ctx) FN(map_pop_elem, 88, ##ctx) FN(map_peek_elem, 89, ##ctx) FN(msg_push_data, 90, ##ctx) FN(msg_pop_data, 91, ##ctx) FN(rc_pointer_rel, 92, ##ctx) FN(spin_lock, 93, ##ctx) FN(spin_unlock, 94, ##ctx) FN(sk_fullsock, 95, ##ctx) FN(tcp_sock, 96, ##ctx) FN(skb_ecn_set_ce, 97, ##ctx) FN(get_listener_sock, 98, ##ctx) FN(skc_lookup_tcp, 99, ##ctx) FN(tcp_check_syncookie, 100, ##ctx) FN(sysctl_get_name, 101, ##ctx) FN(sysctl_get_current_value, 102, ##ctx) FN(sysctl_get_new_value, 103, ##ctx) FN(sysctl_set_new_value, 104, ##ctx) FN(strtol, 105, ##ctx) FN(strtoul, 106, ##ctx) FN(sk_storage_get, 107, ##ctx) FN(sk_storage_delete, 108, ##ctx) FN(send_signal, 109, ##ctx) FN(tcp_gen_syncookie, 110, ##ctx) FN(skb_output, 111, ##ctx) FN(probe_read_user, 112, ##ctx) FN(probe_read_kernel, 113, ##ctx) FN(probe_read_user_str, 114, ##ctx) FN(probe_read_kernel_str, 115, ##ctx) FN(tcp_send_ack, 116, ##ctx) FN(send_signal_thread, 117, ##ctx) FN(jiffies64, 118, ##ctx) FN(read_branch_records, 119, ##ctx) FN(get_ns_current_pid_tgid, 120, ##ctx) FN(xdp_output, 121, ##ctx) FN(get_netns_cookie, 122, ##ctx) FN(get_current_ancestor_cgroup_id, 123, ##ctx) FN(sk_assign, 124, ##ctx) FN(ktime_get_boot_ns, 125, ##ctx) FN(seq_printf, 126, ##ctx) FN(seq_write, 127, ##ctx) FN(sk_cgroup_id, 128, ##ctx) FN(sk_ancestor_cgroup_id, 129, ##ctx) FN(ringbuf_output, 130, ##ctx) FN(ringbuf_reserve, 131, ##ctx) FN(ringbuf_submit, 132, ##ctx) FN(ringbuf_discard, 133, ##ctx) FN(ringbuf_query, 134, ##ctx) FN(csum_level, 135, ##ctx) FN(skc_to_tcp6_sock, 136, ##ctx) FN(skc_to_tcp_sock, 137, ##ctx) FN(skc_to_tcp_timewait_sock, 138, ##ctx) FN(skc_to_tcp_request_sock, 139, ##ctx) FN(skc_to_udp6_sock, 140, ##ctx) FN(get_task_stack, 141, ##ctx) FN(load_hdr_opt, 142, ##ctx) FN(store_hdr_opt, 143, ##ctx) FN(reserve_hdr_opt, 144, ##ctx) FN(inode_storage_get, 145, ##ctx) FN(inode_storage_delete, 146, ##ctx) FN(d_path, 147, ##ctx) FN(copy_from_user, 148, ##ctx) FN(snprintf_btf, 149, ##ctx) FN(seq_printf_btf, 150, ##ctx) FN(skb_cgroup_classid, 151, ##ctx) FN(redirect_neigh, 152, ##ctx) FN(per_cpu_ptr, 153, ##ctx) FN(this_cpu_ptr, 154, ##ctx) FN(redirect_peer, 155, ##ctx) FN(task_storage_get, 156, ##ctx) FN(task_storage_delete, 157, ##ctx) FN(get_current_task_btf, 158, ##ctx) FN(bprm_opts_set, 159, ##ctx) FN(ktime_get_coarse_ns, 160, ##ctx) FN(ima_inode_hash, 161, ##ctx) FN(sock_from_file, 162, ##ctx) FN(check_mtu, 163, ##ctx) FN(for_each_map_elem, 164, ##ctx) FN(snprintf, 165, ##ctx) FN(sys_bpf, 166, ##ctx) FN(btf_find_by_name_kind, 167, ##ctx) FN(sys_close, 168, ##ctx) FN(timer_init, 169, ##ctx) FN(timer_set_callback, 170, ##ctx) FN(timer_start, 171, ##ctx) FN(timer_cancel, 172, ##ctx) FN(get_func_ip, 173, ##ctx) FN(get_attach_cookie, 174, ##ctx) FN(task_pt_regs, 175, ##ctx) FN(get_branch_snapshot, 176, ##ctx) FN(trace_vprintk, 177, ##ctx) FN(skc_to_unix_sock, 178, ##ctx) FN(kallsyms_lookup_name, 179, ##ctx) FN(find_vma, 180, ##ctx) FN(loop, 181, ##ctx) FN(strncmp, 182, ##ctx) FN(get_func_arg, 183, ##ctx) FN(get_func_ret, 184, ##ctx) FN(get_func_arg_cnt, 185, ##ctx) FN(get_retval, 186, ##ctx) FN(set_retval, 187, ##ctx) FN(xdp_get_buff_len, 188, ##ctx) FN(xdp_load_bytes, 189, ##ctx) FN(xdp_store_bytes, 190, ##ctx) FN(copy_from_user_task, 191, ##ctx) FN(skb_set_tstamp, 192, ##ctx) FN(ima_file_hash, 193, ##ctx) FN(kptr_xchg, 194, ##ctx) FN(map_lookup_percpu_elem, 195, ##ctx) FN(skc_to_mptcp_sock, 196, ##ctx) FN(dynptr_from_mem, 197, ##ctx) FN(ringbuf_reserve_dynptr, 198, ##ctx) FN(ringbuf_submit_dynptr, 199, ##ctx) FN(ringbuf_discard_dynptr, 200, ##ctx) FN(dynptr_read, 201, ##ctx) FN(dynptr_write, 202, ##ctx) FN(dynptr_data, 203, ##ctx) FN(tcp_raw_gen_syncookie_ipv4, 204, ##ctx) FN(tcp_raw_gen_syncookie_ipv6, 205, ##ctx) FN(tcp_raw_check_syncookie_ipv4, 206, ##ctx) FN(tcp_raw_check_syncookie_ipv6, 207, ##ctx) FN(ktime_get_tai_ns, 208, ##ctx) FN(user_ringbuf_drain, 209, ##ctx) FN(cgrp_storage_get, 210, ##ctx) FN(cgrp_storage_delete, 211, ##ctx)
#define __BPF_FUNC_MAPPER_APPLY(name,value,FN) FN(name),
@@ -994,7 +1029,7 @@
__u32 btf_id;
__u32 btf_key_type_id;
__u32 btf_value_type_id;
- __u32 : 32;
+ __u32 btf_vmlinux_id;
__u64 map_extra;
} __attribute__((aligned(8)));
struct bpf_btf_info {
@@ -1063,6 +1098,7 @@
__u32 count;
__u32 flags;
__u64 missed;
+ __aligned_u64 cookies;
} kprobe_multi;
struct {
__aligned_u64 path;
@@ -1082,6 +1118,7 @@
__aligned_u64 file_name;
__u32 name_len;
__u32 offset;
+ __u64 cookie;
} uprobe;
struct {
__aligned_u64 func_name;
@@ -1089,14 +1126,19 @@
__u32 offset;
__u64 addr;
__u64 missed;
+ __u64 cookie;
} kprobe;
struct {
__aligned_u64 tp_name;
__u32 name_len;
+ __u32 : 32;
+ __u64 cookie;
} tracepoint;
struct {
__u64 config;
__u32 type;
+ __u32 : 32;
+ __u64 cookie;
} event;
};
} perf_event;
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 5d449f8..a3ebc4f 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -45,6 +45,7 @@
__u64 rsv_excl;
};
#define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0)
+#define BTRFS_QGROUP_INHERIT_FLAGS_SUPP (BTRFS_QGROUP_INHERIT_SET_LIMITS)
struct btrfs_qgroup_inherit {
__u64 flags;
__u64 num_qgroups;
diff --git a/libc/kernel/uapi/linux/can.h b/libc/kernel/uapi/linux/can.h
index 0fc98ae..a913d73 100644
--- a/libc/kernel/uapi/linux/can.h
+++ b/libc/kernel/uapi/linux/can.h
@@ -55,6 +55,9 @@
};
#define CANXL_XLF 0x80
#define CANXL_SEC 0x01
+#define CANXL_VCID_OFFSET 16
+#define CANXL_VCID_VAL_MASK 0xFFUL
+#define CANXL_VCID_MASK (CANXL_VCID_VAL_MASK << CANXL_VCID_OFFSET)
struct canxl_frame {
canid_t prio;
__u8 flags;
diff --git a/libc/kernel/uapi/linux/can/isotp.h b/libc/kernel/uapi/linux/can/isotp.h
index cff12d6..407f6ca 100644
--- a/libc/kernel/uapi/linux/can/isotp.h
+++ b/libc/kernel/uapi/linux/can/isotp.h
@@ -45,6 +45,7 @@
#define CAN_ISOTP_WAIT_TX_DONE 0x0400
#define CAN_ISOTP_SF_BROADCAST 0x0800
#define CAN_ISOTP_CF_BROADCAST 0x1000
+#define CAN_ISOTP_DYN_FC_PARMS 0x2000
#define CAN_ISOTP_DEFAULT_FLAGS 0
#define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00
#define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC
diff --git a/libc/kernel/uapi/linux/can/raw.h b/libc/kernel/uapi/linux/can/raw.h
index 940a852..8e47899 100644
--- a/libc/kernel/uapi/linux/can/raw.h
+++ b/libc/kernel/uapi/linux/can/raw.h
@@ -20,5 +20,15 @@
CAN_RAW_FD_FRAMES,
CAN_RAW_JOIN_FILTERS,
CAN_RAW_XL_FRAMES,
+ CAN_RAW_XL_VCID_OPTS,
};
+struct can_raw_vcid_options {
+ __u8 flags;
+ __u8 tx_vcid;
+ __u8 rx_vcid;
+ __u8 rx_vcid_mask;
+};
+#define CAN_RAW_XL_VCID_TX_SET 0x01
+#define CAN_RAW_XL_VCID_TX_PASS 0x02
+#define CAN_RAW_XL_VCID_RX_FILTER 0x04
#endif
diff --git a/libc/kernel/uapi/linux/dpll.h b/libc/kernel/uapi/linux/dpll.h
index cbefd15..dd692f6 100644
--- a/libc/kernel/uapi/linux/dpll.h
+++ b/libc/kernel/uapi/linux/dpll.h
@@ -22,6 +22,14 @@
__DPLL_LOCK_STATUS_MAX,
DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1)
};
+enum dpll_lock_status_error {
+ DPLL_LOCK_STATUS_ERROR_NONE = 1,
+ DPLL_LOCK_STATUS_ERROR_UNDEFINED,
+ DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN,
+ DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH,
+ __DPLL_LOCK_STATUS_ERROR_MAX,
+ DPLL_LOCK_STATUS_ERROR_MAX = (__DPLL_LOCK_STATUS_ERROR_MAX - 1)
+};
#define DPLL_TEMP_DIVIDER 1000
enum dpll_type {
DPLL_TYPE_PPS = 1,
@@ -71,6 +79,7 @@
DPLL_A_LOCK_STATUS,
DPLL_A_TEMP,
DPLL_A_TYPE,
+ DPLL_A_LOCK_STATUS_ERROR,
__DPLL_A_MAX,
DPLL_A_MAX = (__DPLL_A_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/elf.h b/libc/kernel/uapi/linux/elf.h
index c545fdf..f1cf522 100644
--- a/libc/kernel/uapi/linux/elf.h
+++ b/libc/kernel/uapi/linux/elf.h
@@ -358,6 +358,7 @@
#define NT_ARM_SSVE 0x40b
#define NT_ARM_ZA 0x40c
#define NT_ARM_ZT 0x40d
+#define NT_ARM_FPMR 0x40e
#define NT_ARC_V2 0x600
#define NT_VMCOREDD 0x700
#define NT_MIPS_DSP 0x800
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index e3466cf..48b4544 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -878,6 +878,18 @@
#define IPV4_FLOW 0x10
#define IPV6_FLOW 0x11
#define ETHER_FLOW 0x12
+#define GTPU_V4_FLOW 0x13
+#define GTPU_V6_FLOW 0x14
+#define GTPC_V4_FLOW 0x15
+#define GTPC_V6_FLOW 0x16
+#define GTPC_TEID_V4_FLOW 0x17
+#define GTPC_TEID_V6_FLOW 0x18
+#define GTPU_EH_V4_FLOW 0x19
+#define GTPU_EH_V6_FLOW 0x1a
+#define GTPU_UL_V4_FLOW 0x1b
+#define GTPU_UL_V6_FLOW 0x1c
+#define GTPU_DL_V4_FLOW 0x1d
+#define GTPU_DL_V6_FLOW 0x1e
#define FLOW_EXT 0x80000000
#define FLOW_MAC_EXT 0x40000000
#define FLOW_RSS 0x20000000
@@ -888,6 +900,7 @@
#define RXH_IP_DST (1 << 5)
#define RXH_L4_B_0_1 (1 << 6)
#define RXH_L4_B_2_3 (1 << 7)
+#define RXH_GTP_TEID (1 << 8)
#define RXH_DISCARD (1 << 31)
#define RX_CLS_FLOW_DISC 0xffffffffffffffffULL
#define RX_CLS_FLOW_WAKE 0xfffffffffffffffeULL
diff --git a/libc/kernel/uapi/linux/eventpoll.h b/libc/kernel/uapi/linux/eventpoll.h
index 3468658..7704cb3 100644
--- a/libc/kernel/uapi/linux/eventpoll.h
+++ b/libc/kernel/uapi/linux/eventpoll.h
@@ -35,4 +35,13 @@
#else
#define EPOLL_PACKED
#endif
+struct epoll_params {
+ __u32 busy_poll_usecs;
+ __u16 busy_poll_budget;
+ __u8 prefer_busy_poll;
+ __u8 __pad;
+};
+#define EPOLL_IOC_TYPE 0x8A
+#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params)
+#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params)
#endif
diff --git a/libc/kernel/uapi/linux/fb.h b/libc/kernel/uapi/linux/fb.h
index fda2b05..82f35e7 100644
--- a/libc/kernel/uapi/linux/fb.h
+++ b/libc/kernel/uapi/linux/fb.h
@@ -8,6 +8,7 @@
#define _UAPI_LINUX_FB_H
#include <linux/types.h>
#include <linux/i2c.h>
+#include <linux/vesa.h>
#define FB_MAX 32
#define FBIOGET_VSCREENINFO 0x4600
#define FBIOPUT_VSCREENINFO 0x4601
@@ -235,10 +236,6 @@
__u32 console;
__u32 framebuffer;
};
-#define VESA_NO_BLANKING 0
-#define VESA_VSYNC_SUSPEND 1
-#define VESA_HSYNC_SUSPEND 2
-#define VESA_POWERDOWN 3
enum {
FB_BLANK_UNBLANK = VESA_NO_BLANKING,
FB_BLANK_NORMAL = VESA_NO_BLANKING + 1,
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index f1a8eac..38a2d9e 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -36,6 +36,14 @@
__u64 len;
__u64 minlen;
};
+struct fsuuid2 {
+ __u8 len;
+ __u8 uuid[16];
+};
+struct fs_sysfs_path {
+ __u8 len;
+ __u8 name[128];
+};
#define FILE_DEDUPE_RANGE_SAME 0
#define FILE_DEDUPE_RANGE_DIFFERS 1
struct file_dedupe_range_info {
@@ -141,6 +149,8 @@
#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
#define FS_IOC_GETFSLABEL _IOR(0x94, 49, char[FSLABEL_MAX])
#define FS_IOC_SETFSLABEL _IOW(0x94, 50, char[FSLABEL_MAX])
+#define FS_IOC_GETFSUUID _IOR(0x15, 0, struct fsuuid2)
+#define FS_IOC_GETFSSYSFSPATH _IOR(0x15, 1, struct fs_sysfs_path)
#define FS_SECRM_FL 0x00000001
#define FS_UNRM_FL 0x00000002
#define FS_COMPR_FL 0x00000004
@@ -183,7 +193,8 @@
#define RWF_SYNC (( __kernel_rwf_t) 0x00000004)
#define RWF_NOWAIT (( __kernel_rwf_t) 0x00000008)
#define RWF_APPEND (( __kernel_rwf_t) 0x00000010)
-#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND)
+#define RWF_NOAPPEND (( __kernel_rwf_t) 0x00000020)
+#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT | RWF_APPEND | RWF_NOAPPEND)
#define PAGEMAP_SCAN _IOWR('f', 16, struct pm_scan_arg)
#define PAGE_IS_WPALLOWED (1 << 0)
#define PAGE_IS_WRITTEN (1 << 1)
diff --git a/libc/kernel/uapi/linux/fuse.h b/libc/kernel/uapi/linux/fuse.h
index 8a7d37f..4ac2d2c 100644
--- a/libc/kernel/uapi/linux/fuse.h
+++ b/libc/kernel/uapi/linux/fuse.h
@@ -8,7 +8,7 @@
#define _LINUX_FUSE_H
#include <stdint.h>
#define FUSE_KERNEL_VERSION 7
-#define FUSE_KERNEL_MINOR_VERSION 39
+#define FUSE_KERNEL_MINOR_VERSION 40
#define FUSE_ROOT_ID 1
struct fuse_attr {
uint64_t ino;
@@ -93,6 +93,7 @@
#define FOPEN_STREAM (1 << 4)
#define FOPEN_NOFLUSH (1 << 5)
#define FOPEN_PARALLEL_DIRECT_WRITES (1 << 6)
+#define FOPEN_PASSTHROUGH (1 << 7)
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
#define FUSE_FILE_OPS (1 << 2)
@@ -130,12 +131,10 @@
#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36)
+#define FUSE_PASSTHROUGH (1ULL << 37)
+#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38)
+#define FUSE_HAS_RESEND (1ULL << 39)
#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
-#if FUSE_KERNEL_VERSION > 7 || FUSE_KERNEL_VERSION == 7 && FUSE_KERNEL_MINOR_VERSION >= 36
-#define FUSE_PASSTHROUGH (1ULL << 63)
-#else
-#define FUSE_PASSTHROUGH (1 << 31)
-#endif
#define CUSE_UNRESTRICTED_IOCTL (1 << 0)
#define FUSE_RELEASE_FLUSH (1 << 0)
#define FUSE_RELEASE_FLOCK_UNLOCK (1 << 1)
@@ -215,7 +214,6 @@
FUSE_SYNCFS = 50,
FUSE_TMPFILE = 51,
FUSE_STATX = 52,
- FUSE_CANONICAL_PATH = 2016,
CUSE_INIT = 4096,
CUSE_INIT_BSWAP_RESERVED = 1048576,
FUSE_INIT_BSWAP_RESERVED = 436207616,
@@ -227,6 +225,7 @@
FUSE_NOTIFY_STORE = 4,
FUSE_NOTIFY_RETRIEVE = 5,
FUSE_NOTIFY_DELETE = 6,
+ FUSE_NOTIFY_RESEND = 7,
FUSE_NOTIFY_CODE_MAX,
};
#define FUSE_MIN_READ_BUFFER 8192
@@ -330,7 +329,7 @@
struct fuse_open_out {
uint64_t fh;
uint32_t open_flags;
- uint32_t passthrough_fh;
+ int32_t backing_id;
};
struct fuse_release_in {
uint64_t fh;
@@ -427,7 +426,8 @@
uint16_t max_pages;
uint16_t map_alignment;
uint32_t flags2;
- uint32_t unused[7];
+ uint32_t max_stack_depth;
+ uint32_t unused[6];
};
#define CUSE_INIT_INFO_MAX 4096
struct cuse_init_in {
@@ -496,6 +496,7 @@
uint32_t mode;
uint32_t padding;
};
+#define FUSE_UNIQUE_RESEND (1ULL << 63)
struct fuse_in_header {
uint32_t len;
uint32_t opcode;
@@ -566,9 +567,15 @@
uint64_t dummy3;
uint64_t dummy4;
};
+struct fuse_backing_map {
+ int32_t fd;
+ uint32_t flags;
+ uint64_t padding;
+};
#define FUSE_DEV_IOC_MAGIC 229
#define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
-#define FUSE_DEV_IOC_PASSTHROUGH_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 126, uint32_t)
+#define FUSE_DEV_IOC_BACKING_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 1, struct fuse_backing_map)
+#define FUSE_DEV_IOC_BACKING_CLOSE _IOW(FUSE_DEV_IOC_MAGIC, 2, uint32_t)
struct fuse_lseek_in {
uint64_t fh;
uint64_t offset;
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 19bbfa1..397adfe 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -646,6 +646,7 @@
IFLA_BOND_AD_LACP_ACTIVE,
IFLA_BOND_MISSED_MAX,
IFLA_BOND_NS_IP6_TARGET,
+ IFLA_BOND_COUPLED_CONTROL,
__IFLA_BOND_MAX,
};
#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index 96f285b..0fe5a14 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -528,6 +528,7 @@
#define BTN_DPAD_RIGHT 0x223
#define KEY_ALS_TOGGLE 0x230
#define KEY_ROTATE_LOCK_TOGGLE 0x231
+#define KEY_REFRESH_RATE_TOGGLE 0x232
#define KEY_BUTTONCONFIG 0x240
#define KEY_TASKMANAGER 0x241
#define KEY_JOURNAL 0x242
diff --git a/libc/kernel/uapi/linux/io_uring.h b/libc/kernel/uapi/linux/io_uring.h
index 27675d5..10936f2 100644
--- a/libc/kernel/uapi/linux/io_uring.h
+++ b/libc/kernel/uapi/linux/io_uring.h
@@ -174,6 +174,7 @@
IORING_OP_FUTEX_WAKE,
IORING_OP_FUTEX_WAITV,
IORING_OP_FIXED_FD_INSTALL,
+ IORING_OP_FTRUNCATE,
IORING_OP_LAST,
};
#define IORING_URING_CMD_FIXED (1U << 0)
@@ -316,6 +317,8 @@
IORING_REGISTER_SYNC_CANCEL = 24,
IORING_REGISTER_FILE_ALLOC_RANGE = 25,
IORING_REGISTER_PBUF_STATUS = 26,
+ IORING_REGISTER_NAPI = 27,
+ IORING_UNREGISTER_NAPI = 28,
IORING_REGISTER_LAST,
IORING_REGISTER_USE_REGISTERED_RING = 1U << 31
};
@@ -406,6 +409,12 @@
__u32 head;
__u32 resv[8];
};
+struct io_uring_napi {
+ __u32 busy_poll_to;
+ __u8 prefer_busy_poll;
+ __u8 pad[3];
+ __u64 resv;
+};
enum {
IORING_RESTRICTION_REGISTER_OP = 0,
IORING_RESTRICTION_SQE_OP = 1,
diff --git a/libc/kernel/uapi/linux/ioam6_genl.h b/libc/kernel/uapi/linux/ioam6_genl.h
index 8201bb5..216cd31 100644
--- a/libc/kernel/uapi/linux/ioam6_genl.h
+++ b/libc/kernel/uapi/linux/ioam6_genl.h
@@ -33,4 +33,18 @@
__IOAM6_CMD_MAX,
};
#define IOAM6_CMD_MAX (__IOAM6_CMD_MAX - 1)
+#define IOAM6_GENL_EV_GRP_NAME "ioam6_events"
+enum ioam6_event_type {
+ IOAM6_EVENT_UNSPEC,
+ IOAM6_EVENT_TRACE,
+};
+enum ioam6_event_attr {
+ IOAM6_EVENT_ATTR_UNSPEC,
+ IOAM6_EVENT_ATTR_TRACE_NAMESPACE,
+ IOAM6_EVENT_ATTR_TRACE_NODELEN,
+ IOAM6_EVENT_ATTR_TRACE_TYPE,
+ IOAM6_EVENT_ATTR_TRACE_DATA,
+ __IOAM6_EVENT_ATTR_MAX
+};
+#define IOAM6_EVENT_ATTR_MAX (__IOAM6_EVENT_ATTR_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 0dc806f..62c9872 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -9,7 +9,7 @@
#include <drm/drm.h>
#include <linux/ioctl.h>
#define KFD_IOCTL_MAJOR_VERSION 1
-#define KFD_IOCTL_MINOR_VERSION 14
+#define KFD_IOCTL_MINOR_VERSION 15
struct kfd_ioctl_get_version_args {
__u32 major_version;
__u32 minor_version;
@@ -497,9 +497,12 @@
#define KFD_EC_MASK_QUEUE (KFD_EC_MASK(EC_QUEUE_WAVE_ABORT) | KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | KFD_EC_MASK(EC_QUEUE_WAVE_MATH_ERROR) | KFD_EC_MASK(EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION) | KFD_EC_MASK(EC_QUEUE_WAVE_MEMORY_VIOLATION) | KFD_EC_MASK(EC_QUEUE_WAVE_APERTURE_VIOLATION) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED) | KFD_EC_MASK(EC_QUEUE_PREEMPTION_ERROR) | KFD_EC_MASK(EC_QUEUE_NEW))
#define KFD_EC_MASK_DEVICE (KFD_EC_MASK(EC_DEVICE_QUEUE_DELETE) | KFD_EC_MASK(EC_DEVICE_RAS_ERROR) | KFD_EC_MASK(EC_DEVICE_FATAL_HALT) | KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION) | KFD_EC_MASK(EC_DEVICE_NEW))
#define KFD_EC_MASK_PROCESS (KFD_EC_MASK(EC_PROCESS_RUNTIME) | KFD_EC_MASK(EC_PROCESS_DEVICE_REMOVE))
-#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE))
-#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE))
-#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode) (! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS))
+#define KFD_EC_MASK_PACKET (KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED))
+#define KFD_DBG_EC_IS_VALID(ecode) (ecode > EC_NONE && ecode < EC_MAX)
+#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode) (KFD_DBG_EC_IS_VALID(ecode) && ! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE))
+#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode) (KFD_DBG_EC_IS_VALID(ecode) && ! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE))
+#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode) (KFD_DBG_EC_IS_VALID(ecode) && ! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS))
+#define KFD_DBG_EC_TYPE_IS_PACKET(ecode) (KFD_DBG_EC_IS_VALID(ecode) && ! ! (KFD_EC_MASK(ecode) & KFD_EC_MASK_PACKET))
enum kfd_dbg_runtime_state {
DEBUG_RUNTIME_STATE_DISABLED = 0,
DEBUG_RUNTIME_STATE_ENABLED = 1,
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index ea4f769..ffaf5e6 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -12,6 +12,7 @@
#include <linux/ioctl.h>
#include <asm/kvm.h>
#define KVM_API_VERSION 12
+#define __KVM_HAVE_GUEST_DEBUG
struct kvm_userspace_memory_region {
__u32 slot;
__u32 flags;
@@ -58,24 +59,6 @@
__u32 pad[15];
};
#define KVM_PIT_SPEAKER_DUMMY 1
-struct kvm_s390_skeys {
- __u64 start_gfn;
- __u64 count;
- __u64 skeydata_addr;
- __u32 flags;
- __u32 reserved[9];
-};
-#define KVM_S390_CMMA_PEEK (1 << 0)
-struct kvm_s390_cmma_log {
- __u64 start_gfn;
- __u32 count;
- __u32 flags;
- union {
- __u64 remaining;
- __u64 mask;
- };
- __u64 values;
-};
struct kvm_hyperv_exit {
#define KVM_EXIT_HYPERV_SYNIC 1
#define KVM_EXIT_HYPERV_HCALL 2
@@ -235,11 +218,6 @@
__u16 ipa;
__u32 ipb;
} s390_sieic;
-#define KVM_S390_RESET_POR 1
-#define KVM_S390_RESET_CLEAR 2
-#define KVM_S390_RESET_SUBSYSTEM 4
-#define KVM_S390_RESET_CPU_INIT 8
-#define KVM_S390_RESET_IPL 16
__u64 s390_reset_flags;
struct {
__u64 trans_exc_code;
@@ -389,35 +367,6 @@
__u8 usermode;
__u8 pad[5];
};
-struct kvm_s390_mem_op {
- __u64 gaddr;
- __u64 flags;
- __u32 size;
- __u32 op;
- __u64 buf;
- union {
- struct {
- __u8 ar;
- __u8 key;
- __u8 pad1[6];
- __u64 old_addr;
- };
- __u32 sida_offset;
- __u8 reserved[32];
- };
-};
-#define KVM_S390_MEMOP_LOGICAL_READ 0
-#define KVM_S390_MEMOP_LOGICAL_WRITE 1
-#define KVM_S390_MEMOP_SIDA_READ 2
-#define KVM_S390_MEMOP_SIDA_WRITE 3
-#define KVM_S390_MEMOP_ABSOLUTE_READ 4
-#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5
-#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6
-#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
-#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
-#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2)
-#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0)
-#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1)
struct kvm_interrupt {
__u32 irq;
};
@@ -464,104 +413,6 @@
struct kvm_mp_state {
__u32 mp_state;
};
-struct kvm_s390_psw {
- __u64 mask;
- __u64 addr;
-};
-#define KVM_S390_SIGP_STOP 0xfffe0000u
-#define KVM_S390_PROGRAM_INT 0xfffe0001u
-#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u
-#define KVM_S390_RESTART 0xfffe0003u
-#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u
-#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u
-#define KVM_S390_MCHK 0xfffe1000u
-#define KVM_S390_INT_CLOCK_COMP 0xffff1004u
-#define KVM_S390_INT_CPU_TIMER 0xffff1005u
-#define KVM_S390_INT_VIRTIO 0xffff2603u
-#define KVM_S390_INT_SERVICE 0xffff2401u
-#define KVM_S390_INT_EMERGENCY 0xffff1201u
-#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u
-#define KVM_S390_INT_IO(ai,cssid,ssid,schid) (((schid)) | ((ssid) << 16) | ((cssid) << 18) | ((ai) << 26))
-#define KVM_S390_INT_IO_MIN 0x00000000u
-#define KVM_S390_INT_IO_MAX 0xfffdffffu
-#define KVM_S390_INT_IO_AI_MASK 0x04000000u
-struct kvm_s390_interrupt {
- __u32 type;
- __u32 parm;
- __u64 parm64;
-};
-struct kvm_s390_io_info {
- __u16 subchannel_id;
- __u16 subchannel_nr;
- __u32 io_int_parm;
- __u32 io_int_word;
-};
-struct kvm_s390_ext_info {
- __u32 ext_params;
- __u32 pad;
- __u64 ext_params2;
-};
-struct kvm_s390_pgm_info {
- __u64 trans_exc_code;
- __u64 mon_code;
- __u64 per_address;
- __u32 data_exc_code;
- __u16 code;
- __u16 mon_class_nr;
- __u8 per_code;
- __u8 per_atmid;
- __u8 exc_access_id;
- __u8 per_access_id;
- __u8 op_access_id;
-#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01
-#define KVM_S390_PGM_FLAGS_ILC_0 0x02
-#define KVM_S390_PGM_FLAGS_ILC_1 0x04
-#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06
-#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08
- __u8 flags;
- __u8 pad[2];
-};
-struct kvm_s390_prefix_info {
- __u32 address;
-};
-struct kvm_s390_extcall_info {
- __u16 code;
-};
-struct kvm_s390_emerg_info {
- __u16 code;
-};
-#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01
-struct kvm_s390_stop_info {
- __u32 flags;
-};
-struct kvm_s390_mchk_info {
- __u64 cr14;
- __u64 mcic;
- __u64 failing_storage_address;
- __u32 ext_damage_code;
- __u32 pad;
- __u8 fixed_logout[16];
-};
-struct kvm_s390_irq {
- __u64 type;
- union {
- struct kvm_s390_io_info io;
- struct kvm_s390_ext_info ext;
- struct kvm_s390_pgm_info pgm;
- struct kvm_s390_emerg_info emerg;
- struct kvm_s390_extcall_info extcall;
- struct kvm_s390_prefix_info prefix;
- struct kvm_s390_stop_info stop;
- struct kvm_s390_mchk_info mchk;
- char reserved[64];
- } u;
-};
-struct kvm_s390_irq_state {
- __u64 buf;
- __u32 flags;
- __u32 len;
- __u32 reserved[4];
-};
#define KVM_GUESTDBG_ENABLE 0x00000001
#define KVM_GUESTDBG_SINGLESTEP 0x00000002
struct kvm_guest_debug {
@@ -601,37 +452,6 @@
__u64 args[4];
__u8 pad[64];
};
-#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1 << 0)
-struct kvm_ppc_pvinfo {
- __u32 flags;
- __u32 hcall[4];
- __u8 pad[108];
-};
-#define KVM_PPC_PAGE_SIZES_MAX_SZ 8
-struct kvm_ppc_one_page_size {
- __u32 page_shift;
- __u32 pte_enc;
-};
-struct kvm_ppc_one_seg_page_size {
- __u32 page_shift;
- __u32 slb_enc;
- struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ];
-};
-#define KVM_PPC_PAGE_SIZES_REAL 0x00000001
-#define KVM_PPC_1T_SEGMENTS 0x00000002
-#define KVM_PPC_NO_HASH 0x00000004
-struct kvm_ppc_smmu_info {
- __u64 flags;
- __u32 slb_size;
- __u16 data_keys;
- __u16 instr_keys;
- struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
-};
-struct kvm_ppc_resize_hpt {
- __u64 flags;
- __u32 shift;
- __u32 pad;
-};
#define KVMIO 0xAE
#define KVM_VM_S390_UCONTROL 1
#define KVM_VM_PPC_HV 1
@@ -670,9 +490,7 @@
#define KVM_CAP_IOMMU 18
#define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21
#define KVM_CAP_USER_NMI 22
-#ifdef __KVM_HAVE_GUEST_DEBUG
#define KVM_CAP_SET_GUEST_DEBUG 23
-#endif
#ifdef __KVM_HAVE_PIT
#define KVM_CAP_REINJECT_CONTROL 24
#endif
@@ -901,7 +719,6 @@
#define KVM_CAP_MEMORY_ATTRIBUTES 233
#define KVM_CAP_GUEST_MEMFD 234
#define KVM_CAP_VM_TYPES 235
-#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
__u32 pin;
@@ -956,37 +773,6 @@
__u32 flags;
struct kvm_irq_routing_entry entries[];
};
-#endif
-#ifdef KVM_CAP_MCE
-struct kvm_x86_mce {
- __u64 status;
- __u64 addr;
- __u64 misc;
- __u64 mcg_status;
- __u8 bank;
- __u8 pad1[7];
- __u64 pad2[3];
-};
-#endif
-#ifdef KVM_CAP_XEN_HVM
-#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
-#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
-#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
-#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
-#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
-#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
-#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
-#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
-struct kvm_xen_hvm_config {
- __u32 flags;
- __u32 msr;
- __u64 blob_addr_32;
- __u64 blob_addr_64;
- __u8 blob_size_32;
- __u8 blob_size_64;
- __u8 pad2[30];
-};
-#endif
#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
#define KVM_IRQFD_FLAG_RESAMPLE (1 << 1)
struct kvm_irqfd {
@@ -1118,11 +904,6 @@
#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
#define KVM_SET_USER_MEMORY_REGION2 _IOW(KVMIO, 0x49, struct kvm_userspace_memory_region2)
-struct kvm_s390_ucas_mapping {
- __u64 user_addr;
- __u64 vcpu_addr;
- __u64 length;
-};
#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping)
#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping)
#define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long)
@@ -1245,322 +1026,16 @@
#define KVM_ARM_VCPU_FINALIZE _IOW(KVMIO, 0xc2, int)
#define KVM_S390_NORMAL_RESET _IO(KVMIO, 0xc3)
#define KVM_S390_CLEAR_RESET _IO(KVMIO, 0xc4)
-struct kvm_s390_pv_sec_parm {
- __u64 origin;
- __u64 length;
-};
-struct kvm_s390_pv_unp {
- __u64 addr;
- __u64 size;
- __u64 tweak;
-};
-enum pv_cmd_dmp_id {
- KVM_PV_DUMP_INIT,
- KVM_PV_DUMP_CONFIG_STOR_STATE,
- KVM_PV_DUMP_COMPLETE,
- KVM_PV_DUMP_CPU,
-};
-struct kvm_s390_pv_dmp {
- __u64 subcmd;
- __u64 buff_addr;
- __u64 buff_len;
- __u64 gaddr;
- __u64 reserved[4];
-};
-enum pv_cmd_info_id {
- KVM_PV_INFO_VM,
- KVM_PV_INFO_DUMP,
-};
-struct kvm_s390_pv_info_dump {
- __u64 dump_cpu_buffer_len;
- __u64 dump_config_mem_buffer_per_1m;
- __u64 dump_config_finalize_len;
-};
-struct kvm_s390_pv_info_vm {
- __u64 inst_calls_list[4];
- __u64 max_cpus;
- __u64 max_guests;
- __u64 max_guest_addr;
- __u64 feature_indication;
-};
-struct kvm_s390_pv_info_header {
- __u32 id;
- __u32 len_max;
- __u32 len_written;
- __u32 reserved;
-};
-struct kvm_s390_pv_info {
- struct kvm_s390_pv_info_header header;
- union {
- struct kvm_s390_pv_info_dump dump;
- struct kvm_s390_pv_info_vm vm;
- };
-};
-enum pv_cmd_id {
- KVM_PV_ENABLE,
- KVM_PV_DISABLE,
- KVM_PV_SET_SEC_PARMS,
- KVM_PV_UNPACK,
- KVM_PV_VERIFY,
- KVM_PV_PREP_RESET,
- KVM_PV_UNSHARE_ALL,
- KVM_PV_INFO,
- KVM_PV_DUMP,
- KVM_PV_ASYNC_CLEANUP_PREPARE,
- KVM_PV_ASYNC_CLEANUP_PERFORM,
-};
-struct kvm_pv_cmd {
- __u32 cmd;
- __u16 rc;
- __u16 rrc;
- __u64 data;
- __u32 flags;
- __u32 reserved[3];
-};
#define KVM_S390_PV_COMMAND _IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
#define KVM_X86_SET_MSR_FILTER _IOW(KVMIO, 0xc6, struct kvm_msr_filter)
#define KVM_RESET_DIRTY_RINGS _IO(KVMIO, 0xc7)
#define KVM_XEN_HVM_GET_ATTR _IOWR(KVMIO, 0xc8, struct kvm_xen_hvm_attr)
#define KVM_XEN_HVM_SET_ATTR _IOW(KVMIO, 0xc9, struct kvm_xen_hvm_attr)
-struct kvm_xen_hvm_attr {
- __u16 type;
- __u16 pad[3];
- union {
- __u8 long_mode;
- __u8 vector;
- __u8 runstate_update_flag;
- struct {
- __u64 gfn;
-#define KVM_XEN_INVALID_GFN ((__u64) - 1)
- } shared_info;
- struct {
- __u32 send_port;
- __u32 type;
- __u32 flags;
-#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0)
-#define KVM_XEN_EVTCHN_UPDATE (1 << 1)
-#define KVM_XEN_EVTCHN_RESET (1 << 2)
- union {
- struct {
- __u32 port;
- __u32 vcpu;
- __u32 priority;
- } port;
- struct {
- __u32 port;
- __s32 fd;
- } eventfd;
- __u32 padding[4];
- } deliver;
- } evtchn;
- __u32 xen_version;
- __u64 pad[8];
- } u;
-};
-#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
-#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
-#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
-#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3
-#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4
-#define KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG 0x5
#define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr)
#define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr)
#define KVM_XEN_HVM_EVTCHN_SEND _IOW(KVMIO, 0xd0, struct kvm_irq_routing_xen_evtchn)
#define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2)
#define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2)
-struct kvm_xen_vcpu_attr {
- __u16 type;
- __u16 pad[3];
- union {
- __u64 gpa;
-#define KVM_XEN_INVALID_GPA ((__u64) - 1)
- __u64 pad[8];
- struct {
- __u64 state;
- __u64 state_entry_time;
- __u64 time_running;
- __u64 time_runnable;
- __u64 time_blocked;
- __u64 time_offline;
- } runstate;
- __u32 vcpu_id;
- struct {
- __u32 port;
- __u32 priority;
- __u64 expires_ns;
- } timer;
- __u8 vector;
- } u;
-};
-#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
-#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1
-#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2
-#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
-#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
-#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
-#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6
-#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7
-#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8
-enum sev_cmd_id {
- KVM_SEV_INIT = 0,
- KVM_SEV_ES_INIT,
- KVM_SEV_LAUNCH_START,
- KVM_SEV_LAUNCH_UPDATE_DATA,
- KVM_SEV_LAUNCH_UPDATE_VMSA,
- KVM_SEV_LAUNCH_SECRET,
- KVM_SEV_LAUNCH_MEASURE,
- KVM_SEV_LAUNCH_FINISH,
- KVM_SEV_SEND_START,
- KVM_SEV_SEND_UPDATE_DATA,
- KVM_SEV_SEND_UPDATE_VMSA,
- KVM_SEV_SEND_FINISH,
- KVM_SEV_RECEIVE_START,
- KVM_SEV_RECEIVE_UPDATE_DATA,
- KVM_SEV_RECEIVE_UPDATE_VMSA,
- KVM_SEV_RECEIVE_FINISH,
- KVM_SEV_GUEST_STATUS,
- KVM_SEV_DBG_DECRYPT,
- KVM_SEV_DBG_ENCRYPT,
- KVM_SEV_CERT_EXPORT,
- KVM_SEV_GET_ATTESTATION_REPORT,
- KVM_SEV_SEND_CANCEL,
- KVM_SEV_NR_MAX,
-};
-struct kvm_sev_cmd {
- __u32 id;
- __u64 data;
- __u32 error;
- __u32 sev_fd;
-};
-struct kvm_sev_launch_start {
- __u32 handle;
- __u32 policy;
- __u64 dh_uaddr;
- __u32 dh_len;
- __u64 session_uaddr;
- __u32 session_len;
-};
-struct kvm_sev_launch_update_data {
- __u64 uaddr;
- __u32 len;
-};
-struct kvm_sev_launch_secret {
- __u64 hdr_uaddr;
- __u32 hdr_len;
- __u64 guest_uaddr;
- __u32 guest_len;
- __u64 trans_uaddr;
- __u32 trans_len;
-};
-struct kvm_sev_launch_measure {
- __u64 uaddr;
- __u32 len;
-};
-struct kvm_sev_guest_status {
- __u32 handle;
- __u32 policy;
- __u32 state;
-};
-struct kvm_sev_dbg {
- __u64 src_uaddr;
- __u64 dst_uaddr;
- __u32 len;
-};
-struct kvm_sev_attestation_report {
- __u8 mnonce[16];
- __u64 uaddr;
- __u32 len;
-};
-struct kvm_sev_send_start {
- __u32 policy;
- __u64 pdh_cert_uaddr;
- __u32 pdh_cert_len;
- __u64 plat_certs_uaddr;
- __u32 plat_certs_len;
- __u64 amd_certs_uaddr;
- __u32 amd_certs_len;
- __u64 session_uaddr;
- __u32 session_len;
-};
-struct kvm_sev_send_update_data {
- __u64 hdr_uaddr;
- __u32 hdr_len;
- __u64 guest_uaddr;
- __u32 guest_len;
- __u64 trans_uaddr;
- __u32 trans_len;
-};
-struct kvm_sev_receive_start {
- __u32 handle;
- __u32 policy;
- __u64 pdh_uaddr;
- __u32 pdh_len;
- __u64 session_uaddr;
- __u32 session_len;
-};
-struct kvm_sev_receive_update_data {
- __u64 hdr_uaddr;
- __u32 hdr_len;
- __u64 guest_uaddr;
- __u32 guest_len;
- __u64 trans_uaddr;
- __u32 trans_len;
-};
-#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
-#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
-#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
-struct kvm_assigned_pci_dev {
- __u32 assigned_dev_id;
- __u32 busnr;
- __u32 devfn;
- __u32 flags;
- __u32 segnr;
- union {
- __u32 reserved[11];
- };
-};
-#define KVM_DEV_IRQ_HOST_INTX (1 << 0)
-#define KVM_DEV_IRQ_HOST_MSI (1 << 1)
-#define KVM_DEV_IRQ_HOST_MSIX (1 << 2)
-#define KVM_DEV_IRQ_GUEST_INTX (1 << 8)
-#define KVM_DEV_IRQ_GUEST_MSI (1 << 9)
-#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10)
-#define KVM_DEV_IRQ_HOST_MASK 0x00ff
-#define KVM_DEV_IRQ_GUEST_MASK 0xff00
-struct kvm_assigned_irq {
- __u32 assigned_dev_id;
- __u32 host_irq;
- __u32 guest_irq;
- __u32 flags;
- union {
- __u32 reserved[12];
- };
-};
-struct kvm_assigned_msix_nr {
- __u32 assigned_dev_id;
- __u16 entry_nr;
- __u16 padding;
-};
-#define KVM_MAX_MSIX_PER_DEV 256
-struct kvm_assigned_msix_entry {
- __u32 assigned_dev_id;
- __u32 gsi;
- __u16 entry;
- __u16 padding[3];
-};
-#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
-#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
-#define KVM_ARM_DEV_EL1_VTIMER (1 << 0)
-#define KVM_ARM_DEV_EL1_PTIMER (1 << 1)
-#define KVM_ARM_DEV_PMU (1 << 2)
-struct kvm_hyperv_eventfd {
- __u32 conn_id;
- __s32 fd;
- __u32 flags;
- __u32 padding[3];
-};
-#define KVM_HYPERV_CONN_ID_MASK 0x00ffffff
-#define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0)
#define KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (1 << 0)
#define KVM_DIRTY_LOG_INITIALLY_SET (1 << 1)
#ifndef KVM_DIRTY_LOG_PAGE_OFFSET
@@ -1620,26 +1095,6 @@
#define KVM_X86_NOTIFY_VMEXIT_ENABLED (1ULL << 0)
#define KVM_X86_NOTIFY_VMEXIT_USER (1ULL << 1)
#define KVM_S390_ZPCI_OP _IOW(KVMIO, 0xd1, struct kvm_s390_zpci_op)
-struct kvm_s390_zpci_op {
- __u32 fh;
- __u8 op;
- __u8 pad[3];
- union {
- struct {
- __u64 ibv;
- __u64 sb;
- __u32 flags;
- __u32 noi;
- __u8 isc;
- __u8 sbo;
- __u16 pad;
- } reg_aen;
- __u64 reserved[8];
- } u;
-};
-#define KVM_S390_ZPCIOP_REG_AEN 0
-#define KVM_S390_ZPCIOP_DEREG_AEN 1
-#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0)
#define KVM_SET_MEMORY_ATTRIBUTES _IOW(KVMIO, 0xd2, struct kvm_memory_attributes)
struct kvm_memory_attributes {
__u64 address;
diff --git a/libc/kernel/uapi/linux/lsm.h b/libc/kernel/uapi/linux/lsm.h
index 9d538ee..3a3f152 100644
--- a/libc/kernel/uapi/linux/lsm.h
+++ b/libc/kernel/uapi/linux/lsm.h
@@ -28,6 +28,8 @@
#define LSM_ID_LOCKDOWN 108
#define LSM_ID_BPF 109
#define LSM_ID_LANDLOCK 110
+#define LSM_ID_IMA 111
+#define LSM_ID_EVM 112
#define LSM_ATTR_UNDEF 0
#define LSM_ATTR_CURRENT 100
#define LSM_ATTR_EXEC 101
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index c4d698e..4d24726 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -90,4 +90,5 @@
#define DMA_BUF_MAGIC 0x444d4142
#define DEVMEM_MAGIC 0x454d444d
#define SECRETMEM_MAGIC 0x5345434d
+#define PID_FS_MAGIC 0x50494446
#endif
diff --git a/libc/kernel/uapi/linux/mctp.h b/libc/kernel/uapi/linux/mctp.h
index 8920339..0057842 100644
--- a/libc/kernel/uapi/linux/mctp.h
+++ b/libc/kernel/uapi/linux/mctp.h
@@ -38,9 +38,18 @@
#define MCTP_OPT_ADDR_EXT 1
#define SIOCMCTPALLOCTAG (SIOCPROTOPRIVATE + 0)
#define SIOCMCTPDROPTAG (SIOCPROTOPRIVATE + 1)
+#define SIOCMCTPALLOCTAG2 (SIOCPROTOPRIVATE + 2)
+#define SIOCMCTPDROPTAG2 (SIOCPROTOPRIVATE + 3)
struct mctp_ioc_tag_ctl {
mctp_eid_t peer_addr;
__u8 tag;
__u16 flags;
};
+struct mctp_ioc_tag_ctl2 {
+ unsigned int net;
+ mctp_eid_t peer_addr;
+ mctp_eid_t local_addr;
+ __u16 flags;
+ __u8 tag;
+};
#endif
diff --git a/libc/kernel/uapi/linux/mdio.h b/libc/kernel/uapi/linux/mdio.h
index 7ea6a72..7b51b73 100644
--- a/libc/kernel/uapi/linux/mdio.h
+++ b/libc/kernel/uapi/linux/mdio.h
@@ -110,6 +110,8 @@
#define MDIO_PMA_SPEED_1000 0x0010
#define MDIO_PMA_SPEED_100 0x0020
#define MDIO_PMA_SPEED_10 0x0040
+#define MDIO_PMA_SPEED_2_5G 0x2000
+#define MDIO_PMA_SPEED_5G 0x4000
#define MDIO_PCS_SPEED_10P2B 0x0002
#define MDIO_PCS_SPEED_2_5G 0x0040
#define MDIO_PCS_SPEED_5G 0x0080
@@ -273,6 +275,8 @@
#define MDIO_AN_T1_ADV_L_ACK ADVERTISE_LPACK
#define MDIO_AN_T1_ADV_L_NEXT_PAGE_REQ ADVERTISE_NPAGE
#define MDIO_AN_T1_ADV_M_B10L 0x4000
+#define MDIO_AN_T1_ADV_M_1000BT1 0x0080
+#define MDIO_AN_T1_ADV_M_100BT1 0x0020
#define MDIO_AN_T1_ADV_M_MST 0x0010
#define MDIO_AN_T1_ADV_H_10L_TX_HI_REQ 0x1000
#define MDIO_AN_T1_ADV_H_10L_TX_HI 0x2000
diff --git a/libc/kernel/uapi/linux/mempolicy.h b/libc/kernel/uapi/linux/mempolicy.h
index 6cd8fd1..09ce41e 100644
--- a/libc/kernel/uapi/linux/mempolicy.h
+++ b/libc/kernel/uapi/linux/mempolicy.h
@@ -14,6 +14,7 @@
MPOL_INTERLEAVE,
MPOL_LOCAL,
MPOL_PREFERRED_MANY,
+ MPOL_WEIGHTED_INTERLEAVE,
MPOL_MAX,
};
#define MPOL_F_STATIC_NODES (1 << 15)
diff --git a/libc/kernel/uapi/linux/netdev.h b/libc/kernel/uapi/linux/netdev.h
index 6d90ae4..cbfe26a 100644
--- a/libc/kernel/uapi/linux/netdev.h
+++ b/libc/kernel/uapi/linux/netdev.h
@@ -31,6 +31,9 @@
NETDEV_QUEUE_TYPE_RX,
NETDEV_QUEUE_TYPE_TX,
};
+enum netdev_qstats_scope {
+ NETDEV_QSTATS_SCOPE_QUEUE = 1,
+};
enum {
NETDEV_A_DEV_IFINDEX = 1,
NETDEV_A_DEV_PAD,
@@ -84,6 +87,19 @@
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
};
enum {
+ NETDEV_A_QSTATS_IFINDEX = 1,
+ NETDEV_A_QSTATS_QUEUE_TYPE,
+ NETDEV_A_QSTATS_QUEUE_ID,
+ NETDEV_A_QSTATS_SCOPE,
+ NETDEV_A_QSTATS_RX_PACKETS = 8,
+ NETDEV_A_QSTATS_RX_BYTES,
+ NETDEV_A_QSTATS_TX_PACKETS,
+ NETDEV_A_QSTATS_TX_BYTES,
+ NETDEV_A_QSTATS_RX_ALLOC_FAIL,
+ __NETDEV_A_QSTATS_MAX,
+ NETDEV_A_QSTATS_MAX = (__NETDEV_A_QSTATS_MAX - 1)
+};
+enum {
NETDEV_CMD_DEV_GET = 1,
NETDEV_CMD_DEV_ADD_NTF,
NETDEV_CMD_DEV_DEL_NTF,
@@ -95,6 +111,7 @@
NETDEV_CMD_PAGE_POOL_STATS_GET,
NETDEV_CMD_QUEUE_GET,
NETDEV_CMD_NAPI_GET,
+ NETDEV_CMD_QSTATS_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
};
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index 2216fa8..7922147 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -103,8 +103,9 @@
enum nft_table_flags {
NFT_TABLE_F_DORMANT = 0x1,
NFT_TABLE_F_OWNER = 0x2,
+ NFT_TABLE_F_PERSIST = 0x4,
};
-#define NFT_TABLE_F_MASK (NFT_TABLE_F_DORMANT | NFT_TABLE_F_OWNER)
+#define NFT_TABLE_F_MASK (NFT_TABLE_F_DORMANT | NFT_TABLE_F_OWNER | NFT_TABLE_F_PERSIST)
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
NFTA_TABLE_NAME,
diff --git a/libc/kernel/uapi/linux/nexthop.h b/libc/kernel/uapi/linux/nexthop.h
index ea68f62..5726a66 100644
--- a/libc/kernel/uapi/linux/nexthop.h
+++ b/libc/kernel/uapi/linux/nexthop.h
@@ -26,6 +26,8 @@
__NEXTHOP_GRP_TYPE_MAX,
};
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
+#define NHA_OP_FLAG_DUMP_STATS BIT(0)
+#define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
enum {
NHA_UNSPEC,
NHA_ID,
@@ -41,6 +43,10 @@
NHA_FDB,
NHA_RES_GROUP,
NHA_RES_BUCKET,
+ NHA_OP_FLAGS,
+ NHA_GROUP_STATS,
+ NHA_HW_STATS_ENABLE,
+ NHA_HW_STATS_USED,
__NHA_MAX,
};
#define NHA_MAX (__NHA_MAX - 1)
@@ -63,4 +69,18 @@
__NHA_RES_BUCKET_MAX,
};
#define NHA_RES_BUCKET_MAX (__NHA_RES_BUCKET_MAX - 1)
+enum {
+ NHA_GROUP_STATS_UNSPEC,
+ NHA_GROUP_STATS_ENTRY,
+ __NHA_GROUP_STATS_MAX,
+};
+#define NHA_GROUP_STATS_MAX (__NHA_GROUP_STATS_MAX - 1)
+enum {
+ NHA_GROUP_STATS_ENTRY_UNSPEC,
+ NHA_GROUP_STATS_ENTRY_ID,
+ NHA_GROUP_STATS_ENTRY_PACKETS,
+ NHA_GROUP_STATS_ENTRY_PACKETS_HW,
+ __NHA_GROUP_STATS_ENTRY_MAX,
+};
+#define NHA_GROUP_STATS_ENTRY_MAX (__NHA_GROUP_STATS_ENTRY_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 3286d9b..ddf2b3b 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -527,6 +527,7 @@
NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
NL80211_ATTR_MLO_TTLM_DLINK,
NL80211_ATTR_MLO_TTLM_ULINK,
+ NL80211_ATTR_ASSOC_SPP_AMSDU,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -602,6 +603,7 @@
NL80211_STA_FLAG_AUTHENTICATED,
NL80211_STA_FLAG_TDLS_PEER,
NL80211_STA_FLAG_ASSOCIATED,
+ NL80211_STA_FLAG_SPP_AMSDU,
__NL80211_STA_FLAG_AFTER_LAST,
NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
};
@@ -873,8 +875,9 @@
NL80211_FREQUENCY_ATTR_NO_EHT,
NL80211_FREQUENCY_ATTR_PSD,
NL80211_FREQUENCY_ATTR_DFS_CONCURRENT,
- NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT,
- NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT,
+ NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT,
+ NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT,
+ NL80211_FREQUENCY_ATTR_CAN_MONITOR,
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1
};
@@ -883,6 +886,8 @@
#define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR
#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT NL80211_FREQUENCY_ATTR_IR_CONCURRENT
+#define NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT
+#define NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT
enum nl80211_bitrate_attr {
__NL80211_BITRATE_ATTR_INVALID,
NL80211_BITRATE_ATTR_RATE,
@@ -948,14 +953,16 @@
NL80211_RRF_NO_EHT = 1 << 19,
NL80211_RRF_PSD = 1 << 20,
NL80211_RRF_DFS_CONCURRENT = 1 << 21,
- NL80211_RRF_NO_UHB_VLP_CLIENT = 1 << 22,
- NL80211_RRF_NO_UHB_AFC_CLIENT = 1 << 23,
+ NL80211_RRF_NO_6GHZ_VLP_CLIENT = 1 << 22,
+ NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1 << 23,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS | NL80211_RRF_NO_HT40PLUS)
#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT
+#define NL80211_RRF_NO_UHB_VLP_CLIENT NL80211_RRF_NO_6GHZ_VLP_CLIENT
+#define NL80211_RRF_NO_UHB_AFC_CLIENT NL80211_RRF_NO_6GHZ_AFC_CLIENT
#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
enum nl80211_dfs_regions {
NL80211_DFS_UNSET = 0,
@@ -1120,8 +1127,9 @@
};
enum nl80211_bss_cannot_use_reasons {
NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 1 << 0,
- NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 1 << 1,
+ NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 1 << 1,
};
+#define NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH
enum nl80211_bss {
__NL80211_BSS_INVALID,
NL80211_BSS_BSSID,
@@ -1338,6 +1346,7 @@
NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
NL80211_WOWLAN_TRIG_NET_DETECT,
NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS,
+ NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC,
NUM_NL80211_WOWLAN_TRIG,
MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
};
@@ -1568,6 +1577,7 @@
NL80211_EXT_FEATURE_OWE_OFFLOAD,
NL80211_EXT_FEATURE_OWE_OFFLOAD_AP,
NL80211_EXT_FEATURE_DFS_CONCURRENT,
+ NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
diff --git a/libc/kernel/uapi/linux/pidfd.h b/libc/kernel/uapi/linux/pidfd.h
index 9a49e6a..082b4a0 100644
--- a/libc/kernel/uapi/linux/pidfd.h
+++ b/libc/kernel/uapi/linux/pidfd.h
@@ -9,4 +9,8 @@
#include <linux/types.h>
#include <linux/fcntl.h>
#define PIDFD_NONBLOCK O_NONBLOCK
+#define PIDFD_THREAD O_EXCL
+#define PIDFD_SIGNAL_THREAD (1UL << 0)
+#define PIDFD_SIGNAL_THREAD_GROUP (1UL << 1)
+#define PIDFD_SIGNAL_PROCESS_GROUP (1UL << 2)
#endif
diff --git a/libc/kernel/uapi/linux/psp-sev.h b/libc/kernel/uapi/linux/psp-sev.h
index ffbcf82..82fcbf1 100644
--- a/libc/kernel/uapi/linux/psp-sev.h
+++ b/libc/kernel/uapi/linux/psp-sev.h
@@ -17,6 +17,9 @@
SEV_PEK_CERT_IMPORT,
SEV_GET_ID,
SEV_GET_ID2,
+ SNP_PLATFORM_STATUS,
+ SNP_COMMIT,
+ SNP_SET_CONFIG,
SEV_MAX,
};
typedef enum {
@@ -47,6 +50,12 @@
SEV_RET_RESOURCE_LIMIT,
SEV_RET_SECURE_DATA_INVALID,
SEV_RET_INVALID_KEY = 0x27,
+ SEV_RET_INVALID_PAGE_SIZE,
+ SEV_RET_INVALID_PAGE_STATE,
+ SEV_RET_INVALID_MDATA_ENTRY,
+ SEV_RET_INVALID_PAGE_OWNER,
+ SEV_RET_INVALID_PAGE_AEAD_OFLOW,
+ SEV_RET_RMP_INIT_REQUIRED,
SEV_RET_MAX,
} sev_ret_code;
struct sev_user_data_status {
@@ -82,6 +91,28 @@
__u64 address;
__u32 length;
} __attribute__((__packed__));
+struct sev_user_data_snp_status {
+ __u8 api_major;
+ __u8 api_minor;
+ __u8 state;
+ __u8 is_rmp_initialized : 1;
+ __u8 rsvd : 7;
+ __u32 build_id;
+ __u32 mask_chip_id : 1;
+ __u32 mask_chip_key : 1;
+ __u32 vlek_en : 1;
+ __u32 rsvd1 : 29;
+ __u32 guest_count;
+ __u64 current_tcb_version;
+ __u64 reported_tcb_version;
+} __attribute__((__packed__));
+struct sev_user_data_snp_config {
+ __u64 reported_tcb;
+ __u32 mask_chip_id : 1;
+ __u32 mask_chip_key : 1;
+ __u32 rsvd : 30;
+ __u8 rsvd1[52];
+} __attribute__((__packed__));
struct sev_issue_cmd {
__u32 cmd;
__u64 data;
diff --git a/libc/kernel/uapi/linux/ptp_clock.h b/libc/kernel/uapi/linux/ptp_clock.h
index ca4447e..5014936 100644
--- a/libc/kernel/uapi/linux/ptp_clock.h
+++ b/libc/kernel/uapi/linux/ptp_clock.h
@@ -12,9 +12,11 @@
#define PTP_RISING_EDGE (1 << 1)
#define PTP_FALLING_EDGE (1 << 2)
#define PTP_STRICT_FLAGS (1 << 3)
+#define PTP_EXT_OFFSET (1 << 4)
#define PTP_EXTTS_EDGES (PTP_RISING_EDGE | PTP_FALLING_EDGE)
-#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | PTP_RISING_EDGE | PTP_FALLING_EDGE | PTP_STRICT_FLAGS)
+#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | PTP_RISING_EDGE | PTP_FALLING_EDGE | PTP_STRICT_FLAGS | PTP_EXT_OFFSET)
#define PTP_EXTTS_V1_VALID_FLAGS (PTP_ENABLE_FEATURE | PTP_RISING_EDGE | PTP_FALLING_EDGE)
+#define PTP_EXTTS_EVENT_VALID (PTP_ENABLE_FEATURE)
#define PTP_PEROUT_ONE_SHOT (1 << 0)
#define PTP_PEROUT_DUTY_CYCLE (1 << 1)
#define PTP_PEROUT_PHASE (1 << 2)
diff --git a/libc/kernel/uapi/linux/rkisp1-config.h b/libc/kernel/uapi/linux/rkisp1-config.h
index ac0b5eb..d4206a0 100644
--- a/libc/kernel/uapi/linux/rkisp1-config.h
+++ b/libc/kernel/uapi/linux/rkisp1-config.h
@@ -97,6 +97,7 @@
RKISP1_V11,
RKISP1_V12,
RKISP1_V13,
+ RKISP1_V_IMX8MP,
};
enum rkisp1_cif_isp_histogram_mode {
RKISP1_CIF_ISP_HISTOGRAM_MODE_DISABLE,
diff --git a/libc/kernel/uapi/linux/tc_act/tc_pedit.h b/libc/kernel/uapi/linux/tc_act/tc_pedit.h
index bc7cc06..9635370 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_pedit.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_pedit.h
@@ -53,7 +53,7 @@
tc_gen;
unsigned char nkeys;
unsigned char flags;
- struct tc_pedit_key keys[0];
+ struct tc_pedit_key keys[] __counted_by(nkeys);
};
#define tc_pedit tc_pedit_sel
#endif
diff --git a/libc/kernel/uapi/linux/ublk_cmd.h b/libc/kernel/uapi/linux/ublk_cmd.h
index d05c7c4..8e7732b 100644
--- a/libc/kernel/uapi/linux/ublk_cmd.h
+++ b/libc/kernel/uapi/linux/ublk_cmd.h
@@ -30,6 +30,7 @@
#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_U_CMD_GET_FEATURES _IOR('u', 0x13, struct ublksrv_ctrl_cmd)
+#define UBLK_U_CMD_DEL_DEV_ASYNC _IOR('u', 0x14, struct ublksrv_ctrl_cmd)
#define UBLK_FEATURES_LEN 8
#define UBLK_IO_FETCH_REQ 0x20
#define UBLK_IO_COMMIT_AND_FETCH_REQ 0x21
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index b858bac..6762773 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -286,6 +286,7 @@
#define USB_OTG_SRP (1 << 0)
#define USB_OTG_HNP (1 << 1)
#define USB_OTG_ADP (1 << 2)
+#define USB_OTG_RSP (1 << 3)
#define OTG_STS_SELECTOR 0xF000
struct usb_debug_descriptor {
__u8 bLength;
diff --git a/libc/kernel/uapi/linux/usb/functionfs.h b/libc/kernel/uapi/linux/usb/functionfs.h
index 417093e..095e937 100644
--- a/libc/kernel/uapi/linux/usb/functionfs.h
+++ b/libc/kernel/uapi/linux/usb/functionfs.h
@@ -69,6 +69,12 @@
__le32 dwPropertyDataType;
__le16 wPropertyNameLength;
} __attribute__((packed));
+#define USB_FFS_DMABUF_TRANSFER_MASK 0x0
+struct usb_ffs_dmabuf_transfer_req {
+ int fd;
+ __u32 flags;
+ __u64 length;
+} __attribute__((packed));
struct usb_functionfs_strings_head {
__le32 magic;
__le32 length;
@@ -97,4 +103,7 @@
#define FUNCTIONFS_INTERFACE_REVMAP _IO('g', 128)
#define FUNCTIONFS_ENDPOINT_REVMAP _IO('g', 129)
#define FUNCTIONFS_ENDPOINT_DESC _IOR('g', 130, struct usb_endpoint_descriptor)
+#define FUNCTIONFS_DMABUF_ATTACH _IOW('g', 131, int)
+#define FUNCTIONFS_DMABUF_DETACH _IOW('g', 132, int)
+#define FUNCTIONFS_DMABUF_TRANSFER _IOW('g', 133, struct usb_ffs_dmabuf_transfer_req)
#endif
diff --git a/libc/kernel/uapi/linux/user_events.h b/libc/kernel/uapi/linux/user_events.h
index 7bff0b0..37bf66b 100644
--- a/libc/kernel/uapi/linux/user_events.h
+++ b/libc/kernel/uapi/linux/user_events.h
@@ -9,11 +9,13 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#define USER_EVENTS_SYSTEM "user_events"
+#define USER_EVENTS_MULTI_SYSTEM "user_events_multi"
#define USER_EVENTS_PREFIX "u:"
#define DYN_LOC(offset,size) ((size) << 16 | (offset))
enum user_reg_flag {
USER_EVENT_REG_PERSIST = 1U << 0,
- USER_EVENT_REG_MAX = 1U << 1,
+ USER_EVENT_REG_MULTI_FORMAT = 1U << 1,
+ USER_EVENT_REG_MAX = 1U << 2,
};
struct user_reg {
__u32 size;
diff --git a/libc/kernel/uapi/linux/vdpa.h b/libc/kernel/uapi/linux/vdpa.h
index a8a9515..462d579 100644
--- a/libc/kernel/uapi/linux/vdpa.h
+++ b/libc/kernel/uapi/linux/vdpa.h
@@ -41,6 +41,22 @@
VDPA_ATTR_DEV_VENDOR_ATTR_NAME,
VDPA_ATTR_DEV_VENDOR_ATTR_VALUE,
VDPA_ATTR_DEV_FEATURES,
+ VDPA_ATTR_DEV_BLK_CFG_CAPACITY,
+ VDPA_ATTR_DEV_BLK_CFG_SIZE_MAX,
+ VDPA_ATTR_DEV_BLK_CFG_BLK_SIZE,
+ VDPA_ATTR_DEV_BLK_CFG_SEG_MAX,
+ VDPA_ATTR_DEV_BLK_CFG_NUM_QUEUES,
+ VDPA_ATTR_DEV_BLK_CFG_PHY_BLK_EXP,
+ VDPA_ATTR_DEV_BLK_CFG_ALIGN_OFFSET,
+ VDPA_ATTR_DEV_BLK_CFG_MIN_IO_SIZE,
+ VDPA_ATTR_DEV_BLK_CFG_OPT_IO_SIZE,
+ VDPA_ATTR_DEV_BLK_CFG_MAX_DISCARD_SEC,
+ VDPA_ATTR_DEV_BLK_CFG_MAX_DISCARD_SEG,
+ VDPA_ATTR_DEV_BLK_CFG_DISCARD_SEC_ALIGN,
+ VDPA_ATTR_DEV_BLK_CFG_MAX_WRITE_ZEROES_SEC,
+ VDPA_ATTR_DEV_BLK_CFG_MAX_WRITE_ZEROES_SEG,
+ VDPA_ATTR_DEV_BLK_READ_ONLY,
+ VDPA_ATTR_DEV_BLK_FLUSH,
VDPA_ATTR_MAX,
};
#endif
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 549c079..1563f47 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -4,8 +4,8 @@
* See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
* for more information.
*/
-#define LINUX_VERSION_CODE 395264
+#define LINUX_VERSION_CODE 395520
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
#define LINUX_VERSION_MAJOR 6
-#define LINUX_VERSION_PATCHLEVEL 8
+#define LINUX_VERSION_PATCHLEVEL 9
#define LINUX_VERSION_SUBLEVEL 0
diff --git a/libc/kernel/uapi/linux/vesa.h b/libc/kernel/uapi/linux/vesa.h
new file mode 100644
index 0000000..1bf9946
--- /dev/null
+++ b/libc/kernel/uapi/linux/vesa.h
@@ -0,0 +1,20 @@
+/*
+ * This file is auto-generated. Modifications will be lost.
+ *
+ * See https://android.googlesource.com/platform/bionic/+/master/libc/kernel/
+ * for more information.
+ */
+#ifndef _UAPI_LINUX_VESA_H
+#define _UAPI_LINUX_VESA_H
+enum vesa_blank_mode {
+ VESA_NO_BLANKING = 0,
+#define VESA_NO_BLANKING VESA_NO_BLANKING
+ VESA_VSYNC_SUSPEND = 1,
+#define VESA_VSYNC_SUSPEND VESA_VSYNC_SUSPEND
+ VESA_HSYNC_SUSPEND = 2,
+#define VESA_HSYNC_SUSPEND VESA_HSYNC_SUSPEND
+ VESA_POWERDOWN = VESA_VSYNC_SUSPEND | VESA_HSYNC_SUSPEND,
+#define VESA_POWERDOWN VESA_POWERDOWN
+ VESA_BLANK_MAX = VESA_POWERDOWN,
+};
+#endif
diff --git a/libc/kernel/uapi/linux/vhost.h b/libc/kernel/uapi/linux/vhost.h
index adf0af7..a93212e 100644
--- a/libc/kernel/uapi/linux/vhost.h
+++ b/libc/kernel/uapi/linux/vhost.h
@@ -55,12 +55,13 @@
#define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int)
#define VHOST_VDPA_GET_IOVA_RANGE _IOR(VHOST_VIRTIO, 0x78, struct vhost_vdpa_iova_range)
#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x79, __u32)
-#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32)
-#define VHOST_VDPA_GET_GROUP_NUM _IOR(VHOST_VIRTIO, 0x81, __u32)
#define VHOST_VDPA_GET_AS_NUM _IOR(VHOST_VIRTIO, 0x7A, unsigned int)
#define VHOST_VDPA_GET_VRING_GROUP _IOWR(VHOST_VIRTIO, 0x7B, struct vhost_vring_state)
#define VHOST_VDPA_SET_GROUP_ASID _IOW(VHOST_VIRTIO, 0x7C, struct vhost_vring_state)
#define VHOST_VDPA_SUSPEND _IO(VHOST_VIRTIO, 0x7D)
#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
#define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, struct vhost_vring_state)
+#define VHOST_VDPA_GET_VQS_COUNT _IOR(VHOST_VIRTIO, 0x80, __u32)
+#define VHOST_VDPA_GET_GROUP_NUM _IOR(VHOST_VIRTIO, 0x81, __u32)
+#define VHOST_VDPA_GET_VRING_SIZE _IOWR(VHOST_VIRTIO, 0x82, struct vhost_vring_state)
#endif
diff --git a/libc/kernel/uapi/linux/virtio_gpu.h b/libc/kernel/uapi/linux/virtio_gpu.h
index 7162226..c3f0fcc 100644
--- a/libc/kernel/uapi/linux/virtio_gpu.h
+++ b/libc/kernel/uapi/linux/virtio_gpu.h
@@ -194,6 +194,7 @@
};
#define VIRTIO_GPU_CAPSET_VIRGL 1
#define VIRTIO_GPU_CAPSET_VIRGL2 2
+#define VIRTIO_GPU_CAPSET_VENUS 4
struct virtio_gpu_get_capset_info {
struct virtio_gpu_ctrl_hdr hdr;
__le32 capset_index;
diff --git a/libc/kernel/uapi/linux/virtio_pci.h b/libc/kernel/uapi/linux/virtio_pci.h
index 013548c..8921155 100644
--- a/libc/kernel/uapi/linux/virtio_pci.h
+++ b/libc/kernel/uapi/linux/virtio_pci.h
@@ -126,30 +126,30 @@
#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_WRITE 0x4
#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5
#define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6
-struct __attribute__((__packed__)) virtio_admin_cmd_hdr {
+struct virtio_admin_cmd_hdr {
__le16 opcode;
__le16 group_type;
__u8 reserved1[12];
__le64 group_member_id;
};
-struct __attribute__((__packed__)) virtio_admin_cmd_status {
+struct virtio_admin_cmd_status {
__le16 status;
__le16 status_qualifier;
__u8 reserved2[4];
};
-struct __attribute__((__packed__)) virtio_admin_cmd_legacy_wr_data {
+struct virtio_admin_cmd_legacy_wr_data {
__u8 offset;
__u8 reserved[7];
__u8 registers[];
};
-struct __attribute__((__packed__)) virtio_admin_cmd_legacy_rd_data {
+struct virtio_admin_cmd_legacy_rd_data {
__u8 offset;
};
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_END 0
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_DEV 0x1
#define VIRTIO_ADMIN_CMD_NOTIFY_INFO_FLAGS_OWNER_MEM 0x2
#define VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO 4
-struct __attribute__((__packed__)) virtio_admin_cmd_notify_info_data {
+struct virtio_admin_cmd_notify_info_data {
__u8 flags;
__u8 bar;
__u8 padding[6];
diff --git a/libc/kernel/uapi/linux/virtio_snd.h b/libc/kernel/uapi/linux/virtio_snd.h
index e4ec8cd..7318e29 100644
--- a/libc/kernel/uapi/linux/virtio_snd.h
+++ b/libc/kernel/uapi/linux/virtio_snd.h
@@ -7,10 +7,14 @@
#ifndef VIRTIO_SND_IF_H
#define VIRTIO_SND_IF_H
#include <linux/virtio_types.h>
+enum {
+ VIRTIO_SND_F_CTLS = 0
+};
struct virtio_snd_config {
__le32 jacks;
__le32 streams;
__le32 chmaps;
+ __le32 controls;
};
enum {
VIRTIO_SND_VQ_CONTROL = 0,
@@ -33,10 +37,18 @@
VIRTIO_SND_R_PCM_START,
VIRTIO_SND_R_PCM_STOP,
VIRTIO_SND_R_CHMAP_INFO = 0x0200,
+ VIRTIO_SND_R_CTL_INFO = 0x0300,
+ VIRTIO_SND_R_CTL_ENUM_ITEMS,
+ VIRTIO_SND_R_CTL_READ,
+ VIRTIO_SND_R_CTL_WRITE,
+ VIRTIO_SND_R_CTL_TLV_READ,
+ VIRTIO_SND_R_CTL_TLV_WRITE,
+ VIRTIO_SND_R_CTL_TLV_COMMAND,
VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
VIRTIO_SND_EVT_JACK_DISCONNECTED,
VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
VIRTIO_SND_EVT_PCM_XRUN,
+ VIRTIO_SND_EVT_CTL_NOTIFY = 0x1200,
VIRTIO_SND_S_OK = 0x8000,
VIRTIO_SND_S_BAD_MSG,
VIRTIO_SND_S_NOT_SUPP,
@@ -209,4 +221,83 @@
__u8 channels;
__u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
};
+struct virtio_snd_ctl_hdr {
+ struct virtio_snd_hdr hdr;
+ __le32 control_id;
+};
+enum {
+ VIRTIO_SND_CTL_ROLE_UNDEFINED = 0,
+ VIRTIO_SND_CTL_ROLE_VOLUME,
+ VIRTIO_SND_CTL_ROLE_MUTE,
+ VIRTIO_SND_CTL_ROLE_GAIN
+};
+enum {
+ VIRTIO_SND_CTL_TYPE_BOOLEAN = 0,
+ VIRTIO_SND_CTL_TYPE_INTEGER,
+ VIRTIO_SND_CTL_TYPE_INTEGER64,
+ VIRTIO_SND_CTL_TYPE_ENUMERATED,
+ VIRTIO_SND_CTL_TYPE_BYTES,
+ VIRTIO_SND_CTL_TYPE_IEC958
+};
+enum {
+ VIRTIO_SND_CTL_ACCESS_READ = 0,
+ VIRTIO_SND_CTL_ACCESS_WRITE,
+ VIRTIO_SND_CTL_ACCESS_VOLATILE,
+ VIRTIO_SND_CTL_ACCESS_INACTIVE,
+ VIRTIO_SND_CTL_ACCESS_TLV_READ,
+ VIRTIO_SND_CTL_ACCESS_TLV_WRITE,
+ VIRTIO_SND_CTL_ACCESS_TLV_COMMAND
+};
+struct virtio_snd_ctl_info {
+ struct virtio_snd_info hdr;
+ __le32 role;
+ __le32 type;
+ __le32 access;
+ __le32 count;
+ __le32 index;
+ __u8 name[44];
+ union {
+ struct {
+ __le32 min;
+ __le32 max;
+ __le32 step;
+ } integer;
+ struct {
+ __le64 min;
+ __le64 max;
+ __le64 step;
+ } integer64;
+ struct {
+ __le32 items;
+ } enumerated;
+ } value;
+};
+struct virtio_snd_ctl_enum_item {
+ __u8 item[64];
+};
+struct virtio_snd_ctl_iec958 {
+ __u8 status[24];
+ __u8 subcode[147];
+ __u8 pad;
+ __u8 dig_subframe[4];
+};
+struct virtio_snd_ctl_value {
+ union {
+ __le32 integer[128];
+ __le64 integer64[64];
+ __le32 enumerated[128];
+ __u8 bytes[512];
+ struct virtio_snd_ctl_iec958 iec958;
+ } value;
+};
+enum {
+ VIRTIO_SND_CTL_EVT_MASK_VALUE = 0,
+ VIRTIO_SND_CTL_EVT_MASK_INFO,
+ VIRTIO_SND_CTL_EVT_MASK_TLV
+};
+struct virtio_snd_ctl_event {
+ struct virtio_snd_hdr hdr;
+ __le16 control_id;
+ __le16 mask;
+};
#endif
diff --git a/libc/kernel/uapi/rdma/hns-abi.h b/libc/kernel/uapi/rdma/hns-abi.h
index 54a5672..5b0f700 100644
--- a/libc/kernel/uapi/rdma/hns-abi.h
+++ b/libc/kernel/uapi/rdma/hns-abi.h
@@ -37,6 +37,15 @@
__u32 srqn;
__u32 cap_flags;
};
+enum hns_roce_congest_type_flags {
+ HNS_ROCE_CREATE_QP_FLAGS_DCQCN,
+ HNS_ROCE_CREATE_QP_FLAGS_LDCP,
+ HNS_ROCE_CREATE_QP_FLAGS_HC3,
+ HNS_ROCE_CREATE_QP_FLAGS_DIP,
+};
+enum hns_roce_create_qp_comp_mask {
+ HNS_ROCE_CREATE_QP_MASK_CONGEST_TYPE = 1 << 0,
+};
struct hns_roce_ib_create_qp {
__aligned_u64 buf_addr;
__aligned_u64 db_addr;
@@ -45,6 +54,9 @@
__u8 sq_no_prefetch;
__u8 reserved[5];
__aligned_u64 sdb_addr;
+ __aligned_u64 comp_mask;
+ __aligned_u64 create_flags;
+ __aligned_u64 cong_type_flags;
};
enum hns_roce_qp_cap_flags {
HNS_ROCE_QP_CAP_RQ_RECORD_DB = 1 << 0,
@@ -73,6 +85,8 @@
__u32 reserved;
__u32 config;
__u32 max_inline_data;
+ __u8 congest_type;
+ __u8 reserved0[7];
};
struct hns_roce_ib_alloc_ucontext {
__u32 config;
diff --git a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
index bac5017..d98e8fa 100644
--- a/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
+++ b/libc/kernel/uapi/scsi/scsi_bsg_mpi3mr.h
@@ -176,7 +176,7 @@
__u8 mpi_reply_type;
__u8 rsvd1;
__u16 rsvd2;
- __u8 reply_buf[1];
+ __u8 reply_buf[];
};
struct mpi3mr_buf_entry {
__u8 buf_type;
diff --git a/libc/kernel/uapi/sound/intel/avs/tokens.h b/libc/kernel/uapi/sound/intel/avs/tokens.h
index 6a8ed8a..01b20a5 100644
--- a/libc/kernel/uapi/sound/intel/avs/tokens.h
+++ b/libc/kernel/uapi/sound/intel/avs/tokens.h
@@ -15,6 +15,8 @@
AVS_TKN_MANIFEST_NUM_MODCFGS_EXT_U32 = 6,
AVS_TKN_MANIFEST_NUM_PPLCFGS_U32 = 7,
AVS_TKN_MANIFEST_NUM_BINDINGS_U32 = 8,
+ AVS_TKN_MANIFEST_NUM_CONDPATH_TMPLS_U32 = 9,
+ AVS_TKN_MANIFEST_NUM_INIT_CONFIGS_U32 = 10,
AVS_TKN_LIBRARY_ID_U32 = 101,
AVS_TKN_LIBRARY_NAME_STRING = 102,
AVS_TKN_AFMT_ID_U32 = 201,
@@ -89,6 +91,8 @@
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
+ AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32 = 1708,
+ AVS_TKN_MOD_INIT_CONFIG_ID_U32 = 1709,
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
AVS_TKN_PATH_ID_U32 = 1901,
AVS_TKN_PATH_FE_FMT_ID_U32 = 1902,
@@ -97,5 +101,8 @@
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
AVS_TKN_KCONTROL_ID_U32 = 2301,
+ AVS_TKN_INIT_CONFIG_ID_U32 = 2401,
+ AVS_TKN_INIT_CONFIG_PARAM_U8 = 2402,
+ AVS_TKN_INIT_CONFIG_LENGTH_U32 = 2403,
};
#endif
diff --git a/libc/kernel/uapi/sound/sof/tokens.h b/libc/kernel/uapi/sound/sof/tokens.h
index b55a895..c4257d9 100644
--- a/libc/kernel/uapi/sound/sof/tokens.h
+++ b/libc/kernel/uapi/sound/sof/tokens.h
@@ -128,4 +128,6 @@
#define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
#define SOF_TKN_IMX_MICFIL_RATE 2000
#define SOF_TKN_IMX_MICFIL_CH 2001
+#define SOF_TKN_AMD_ACP_SDW_RATE 2100
+#define SOF_TKN_AMD_ACP_SDW_CH 2101
#endif
diff --git a/libc/malloc_debug/MapData.cpp b/libc/malloc_debug/MapData.cpp
index b22c109..c58882a 100644
--- a/libc/malloc_debug/MapData.cpp
+++ b/libc/malloc_debug/MapData.cpp
@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
+#include <sys/uio.h>
+#include <unistd.h>
#include <vector>
@@ -69,148 +71,132 @@
MapEntry* entry = new MapEntry(start, end, offset, name, name_len, flags);
if (!(flags & PROT_READ)) {
- // Any unreadable map will just get a zero load bias.
- entry->load_bias = 0;
- entry->init = true;
- entry->valid = false;
+ // This will make sure that an unreadable map will prevent attempts to read
+ // elf data from the map.
+ entry->SetInvalid();
}
return entry;
}
-template <typename T>
-static inline bool get_val(MapEntry* entry, uintptr_t addr, T* store) {
- if (!(entry->flags & PROT_READ) || addr < entry->start || addr + sizeof(T) > entry->end) {
- return false;
+void MapEntry::Init() {
+ if (init_) {
+ return;
}
- // Make sure the address is aligned properly.
- if (addr & (sizeof(T) - 1)) {
- return false;
- }
- *store = *reinterpret_cast<T*>(addr);
- return true;
-}
+ init_ = true;
-static bool valid_elf(MapEntry* entry) {
- uintptr_t addr = entry->start;
- uintptr_t end;
- if (__builtin_add_overflow(addr, SELFMAG, &end) || end >= entry->end) {
- return false;
+ uintptr_t end_addr;
+ if (__builtin_add_overflow(start_, SELFMAG, &end_addr) || end_addr >= end_) {
+ return;
}
- return memcmp(reinterpret_cast<void*>(addr), ELFMAG, SELFMAG) == 0;
-}
-
-static void read_loadbias(MapEntry* entry) {
- entry->load_bias = 0;
- uintptr_t addr = entry->start;
ElfW(Ehdr) ehdr;
- if (!get_val<ElfW(Half)>(entry, addr + offsetof(ElfW(Ehdr), e_phnum), &ehdr.e_phnum)) {
- return;
+ struct iovec src_io = {.iov_base = reinterpret_cast<void*>(start_), .iov_len = SELFMAG};
+ struct iovec dst_io = {.iov_base = ehdr.e_ident, .iov_len = SELFMAG};
+ ssize_t rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+ valid_ = rc == SELFMAG && IS_ELF(ehdr);
+}
+
+uintptr_t MapEntry::GetLoadBias() {
+ if (!valid_) {
+ return 0;
}
- if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Ehdr), e_phoff), &ehdr.e_phoff)) {
- return;
+
+ if (load_bias_read_) {
+ return load_bias_;
}
- addr += ehdr.e_phoff;
+
+ load_bias_read_ = true;
+
+ ElfW(Ehdr) ehdr;
+ struct iovec src_io = {.iov_base = reinterpret_cast<void*>(start_), .iov_len = sizeof(ehdr)};
+ struct iovec dst_io = {.iov_base = &ehdr, .iov_len = sizeof(ehdr)};
+ ssize_t rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+ if (rc != sizeof(ehdr)) {
+ return 0;
+ }
+
+ uintptr_t addr = start_ + ehdr.e_phoff;
for (size_t i = 0; i < ehdr.e_phnum; i++) {
ElfW(Phdr) phdr;
- if (!get_val<ElfW(Word)>(entry, addr + offsetof(ElfW(Phdr), p_type), &phdr.p_type)) {
- return;
- }
- if (!get_val<ElfW(Word)>(entry, addr + offsetof(ElfW(Phdr), p_flags), &phdr.p_flags)) {
- return;
- }
- if (!get_val<ElfW(Off)>(entry, addr + offsetof(ElfW(Phdr), p_offset), &phdr.p_offset)) {
- return;
+
+ src_io.iov_base = reinterpret_cast<void*>(addr);
+ src_io.iov_len = sizeof(phdr);
+ dst_io.iov_base = &phdr;
+ dst_io.iov_len = sizeof(phdr);
+ rc = process_vm_readv(getpid(), &dst_io, 1, &src_io, 1, 0);
+ if (rc != sizeof(phdr)) {
+ return 0;
}
if ((phdr.p_type == PT_LOAD) && (phdr.p_flags & PF_X) ) {
- if (!get_val<ElfW(Addr)>(entry, addr + offsetof(ElfW(Phdr), p_vaddr), &phdr.p_vaddr)) {
- return;
- }
- entry->load_bias = phdr.p_vaddr - phdr.p_offset;
- return;
+ load_bias_ = phdr.p_vaddr - phdr.p_offset;
+ return load_bias_;
}
addr += sizeof(phdr);
}
+ return 0;
}
-static void inline init(MapEntry* entry) {
- if (entry->init) {
- return;
- }
- entry->init = true;
- if (valid_elf(entry)) {
- entry->valid = true;
- read_loadbias(entry);
- }
-}
-
-bool MapData::ReadMaps() {
+void MapData::ReadMaps() {
+ std::lock_guard<std::mutex> lock(m_);
FILE* fp = fopen("/proc/self/maps", "re");
if (fp == nullptr) {
- return false;
+ return;
}
+ ClearEntries();
+
std::vector<char> buffer(1024);
while (fgets(buffer.data(), buffer.size(), fp) != nullptr) {
MapEntry* entry = parse_line(buffer.data());
if (entry == nullptr) {
- fclose(fp);
- return false;
+ break;
}
-
- auto it = entries_.find(entry);
- if (it == entries_.end()) {
- entries_.insert(entry);
- } else {
- delete entry;
- }
+ entries_.insert(entry);
}
fclose(fp);
- return true;
}
-MapData::~MapData() {
+void MapData::ClearEntries() {
for (auto* entry : entries_) {
delete entry;
}
entries_.clear();
}
+MapData::~MapData() {
+ ClearEntries();
+}
+
// Find the containing map info for the PC.
const MapEntry* MapData::find(uintptr_t pc, uintptr_t* rel_pc) {
MapEntry pc_entry(pc);
std::lock_guard<std::mutex> lock(m_);
-
auto it = entries_.find(&pc_entry);
if (it == entries_.end()) {
- ReadMaps();
- }
- it = entries_.find(&pc_entry);
- if (it == entries_.end()) {
return nullptr;
}
MapEntry* entry = *it;
- init(entry);
+ entry->Init();
if (rel_pc != nullptr) {
// Need to check to see if this is a read-execute map and the read-only
// map is the previous one.
- if (!entry->valid && it != entries_.begin()) {
+ if (!entry->valid() && it != entries_.begin()) {
MapEntry* prev_entry = *--it;
- if (prev_entry->flags == PROT_READ && prev_entry->offset < entry->offset &&
- prev_entry->name == entry->name) {
- init(prev_entry);
+ if (prev_entry->flags() == PROT_READ && prev_entry->offset() < entry->offset() &&
+ prev_entry->name() == entry->name()) {
+ prev_entry->Init();
- if (prev_entry->valid) {
- entry->elf_start_offset = prev_entry->offset;
- *rel_pc = pc - entry->start + entry->offset + prev_entry->load_bias;
+ if (prev_entry->valid()) {
+ entry->set_elf_start_offset(prev_entry->offset());
+ *rel_pc = pc - entry->start() + entry->offset() + prev_entry->GetLoadBias();
return entry;
}
}
}
- *rel_pc = pc - entry->start + entry->offset + entry->load_bias;
+ *rel_pc = pc - entry->start() + entry->offset() + entry->GetLoadBias();
}
return entry;
}
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index f2b3c1c..13bf9cb 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -36,26 +36,50 @@
#include <platform/bionic/macros.h>
-struct MapEntry {
- MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len, int flags)
- : start(start), end(end), offset(offset), name(name, name_len), flags(flags) {}
+class MapEntry {
+ public:
+ MapEntry() = default;
+ MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len,
+ int flags)
+ : start_(start), end_(end), offset_(offset), name_(name, name_len), flags_(flags) {}
- explicit MapEntry(uintptr_t pc) : start(pc), end(pc) {}
+ explicit MapEntry(uintptr_t pc) : start_(pc), end_(pc) {}
- uintptr_t start;
- uintptr_t end;
- uintptr_t offset;
- uintptr_t load_bias;
- uintptr_t elf_start_offset = 0;
- std::string name;
- int flags;
- bool init = false;
- bool valid = false;
+ void Init();
+
+ uintptr_t GetLoadBias();
+
+ void SetInvalid() {
+ valid_ = false;
+ init_ = true;
+ load_bias_read_ = true;
+ }
+
+ bool valid() { return valid_; }
+ uintptr_t start() const { return start_; }
+ uintptr_t end() const { return end_; }
+ uintptr_t offset() const { return offset_; }
+ uintptr_t elf_start_offset() const { return elf_start_offset_; }
+ void set_elf_start_offset(uintptr_t elf_start_offset) { elf_start_offset_ = elf_start_offset; }
+ const std::string& name() const { return name_; }
+ int flags() const { return flags_; }
+
+ private:
+ uintptr_t start_;
+ uintptr_t end_;
+ uintptr_t offset_;
+ uintptr_t load_bias_ = 0;
+ uintptr_t elf_start_offset_ = 0;
+ std::string name_;
+ int flags_;
+ bool init_ = false;
+ bool valid_ = false;
+ bool load_bias_read_ = false;
};
// Ordering comparator that returns equivalence for overlapping entries
struct compare_entries {
- bool operator()(const MapEntry* a, const MapEntry* b) const { return a->end <= b->start; }
+ bool operator()(const MapEntry* a, const MapEntry* b) const { return a->end() <= b->start(); }
};
class MapData {
@@ -65,11 +89,15 @@
const MapEntry* find(uintptr_t pc, uintptr_t* rel_pc = nullptr);
- private:
- bool ReadMaps();
+ size_t NumMaps() { return entries_.size(); }
+ void ReadMaps();
+
+ private:
std::mutex m_;
std::set<MapEntry*, compare_entries> entries_;
+ void ClearEntries();
+
BIONIC_DISALLOW_COPY_AND_ASSIGN(MapData);
};
diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp
index ecb3a80..6a32fca 100644
--- a/libc/malloc_debug/backtrace.cpp
+++ b/libc/malloc_debug/backtrace.cpp
@@ -50,7 +50,7 @@
typedef struct _Unwind_Context __unwind_context;
static MapData g_map_data;
-static const MapEntry* g_current_code_map = nullptr;
+static MapEntry g_current_code_map;
static _Unwind_Reason_Code find_current_map(__unwind_context* context, void*) {
uintptr_t ip = _Unwind_GetIP(context);
@@ -58,11 +58,15 @@
if (ip == 0) {
return _URC_END_OF_STACK;
}
- g_current_code_map = g_map_data.find(ip);
+ auto map = g_map_data.find(ip);
+ if (map != nullptr) {
+ g_current_code_map = *map;
+ }
return _URC_END_OF_STACK;
}
void backtrace_startup() {
+ g_map_data.ReadMaps();
_Unwind_Backtrace(find_current_map, nullptr);
}
@@ -98,7 +102,8 @@
}
// Do not record the frames that fall in our own shared library.
- if (g_current_code_map && (ip >= g_current_code_map->start) && ip < g_current_code_map->end) {
+ if (g_current_code_map.start() != 0 && (ip >= g_current_code_map.start()) &&
+ ip < g_current_code_map.end()) {
return _URC_NO_REASON;
}
@@ -113,6 +118,10 @@
}
std::string backtrace_string(const uintptr_t* frames, size_t frame_count) {
+ if (g_map_data.NumMaps() == 0) {
+ g_map_data.ReadMaps();
+ }
+
std::string str;
for (size_t frame_num = 0; frame_num < frame_count; frame_num++) {
@@ -130,14 +139,15 @@
uintptr_t rel_pc = offset;
const MapEntry* entry = g_map_data.find(frames[frame_num], &rel_pc);
- const char* soname = (entry != nullptr) ? entry->name.c_str() : info.dli_fname;
+ const char* soname = (entry != nullptr) ? entry->name().c_str() : info.dli_fname;
if (soname == nullptr) {
soname = "<unknown>";
}
char offset_buf[128];
- if (entry != nullptr && entry->elf_start_offset != 0) {
- snprintf(offset_buf, sizeof(offset_buf), " (offset 0x%" PRIxPTR ")", entry->elf_start_offset);
+ if (entry != nullptr && entry->elf_start_offset() != 0) {
+ snprintf(offset_buf, sizeof(offset_buf), " (offset 0x%" PRIxPTR ")",
+ entry->elf_start_offset());
} else {
offset_buf[0] = '\0';
}
@@ -167,5 +177,6 @@
}
void backtrace_log(const uintptr_t* frames, size_t frame_count) {
+ g_map_data.ReadMaps();
error_log_string(backtrace_string(frames, frame_count).c_str());
}
diff --git a/libc/platform/bionic/page.h b/libc/platform/bionic/page.h
index 65faba4..4dbe4ba 100644
--- a/libc/platform/bionic/page.h
+++ b/libc/platform/bionic/page.h
@@ -32,11 +32,13 @@
#endif
}
-constexpr size_t max_page_size() {
+// The maximum page size supported on any Android device. As
+// of API level 35, this is limited by ART.
+constexpr size_t max_android_page_size() {
#if defined(PAGE_SIZE)
return PAGE_SIZE;
#else
- return 65536;
+ return 16384;
#endif
}
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index bbe35e5..f269125 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -30,11 +30,11 @@
template <typename T>
union WriteProtectedContents {
T value;
- char padding[max_page_size()];
+ char padding[max_android_page_size()];
WriteProtectedContents() = default;
BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
-} __attribute__((aligned(max_page_size())));
+} __attribute__((aligned(max_android_page_size())));
// Write protected wrapper class that aligns its contents to a page boundary,
// and sets the memory protection to be non-writable, except when being modified
@@ -42,8 +42,8 @@
template <typename T>
class WriteProtected {
public:
- static_assert(sizeof(T) < max_page_size(),
- "WriteProtected only supports contents up to max_page_size()");
+ static_assert(sizeof(T) < max_android_page_size(),
+ "WriteProtected only supports contents up to max_android_page_size()");
WriteProtected() = default;
BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
@@ -89,7 +89,7 @@
// ourselves.
addr = untag_address(addr);
#endif
- if (mprotect(reinterpret_cast<void*>(addr), max_page_size(), prot) == -1) {
+ if (mprotect(reinterpret_cast<void*>(addr), max_android_page_size(), prot) == -1) {
async_safe_fatal("WriteProtected mprotect %x failed: %s", prot, strerror(errno));
}
}
diff --git a/libc/private/bionic_allocator.h b/libc/private/bionic_allocator.h
index 342fd51..9872669 100644
--- a/libc/private/bionic_allocator.h
+++ b/libc/private/bionic_allocator.h
@@ -28,13 +28,9 @@
#pragma once
-#include <errno.h>
-#include <stdlib.h>
#include <sys/cdefs.h>
-#include <sys/mman.h>
-#include <sys/prctl.h>
#include <stddef.h>
-#include <unistd.h>
+#include <stdint.h>
const uint32_t kSmallObjectMaxSizeLog2 = 10;
const uint32_t kSmallObjectMinSizeLog2 = 4;
@@ -120,7 +116,8 @@
inline void* alloc_impl(size_t align, size_t size);
inline page_info* get_page_info_unchecked(void* ptr);
inline page_info* get_page_info(void* ptr);
- BionicSmallObjectAllocator* get_small_object_allocator(uint32_t type);
+ BionicSmallObjectAllocator* get_small_object_allocator_unchecked(uint32_t type);
+ BionicSmallObjectAllocator* get_small_object_allocator(page_info* pi, void* ptr);
void initialize_allocators();
BionicSmallObjectAllocator* allocators_;
diff --git a/libc/private/bionic_elf_dtv_offset.h b/libc/private/bionic_elf_dtv_offset.h
new file mode 100644
index 0000000..8d9f3b9
--- /dev/null
+++ b/libc/private/bionic_elf_dtv_offset.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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 defined(__riscv)
+// TLS_DTV_OFFSET is a constant used in relocation fields, defined in RISC-V ELF Specification[1]
+// The front of the TCB contains a pointer to the DTV, and each pointer in DTV
+// points to 0x800 past the start of a TLS block to make full use of the range
+// of load/store instructions, refer to [2].
+//
+// [1]: RISC-V ELF Specification.
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#constants
+// [2]: Documentation of TLS data structures
+// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/53
+#define TLS_DTV_OFFSET 0x800
+#else
+#define TLS_DTV_OFFSET 0
+#endif
diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h
index 3a7b381..04297ad 100644
--- a/libc/private/bionic_elf_tls.h
+++ b/libc/private/bionic_elf_tls.h
@@ -34,6 +34,8 @@
#include <stdint.h>
#include <sys/cdefs.h>
+#include "bionic_elf_dtv_offset.h"
+
__LIBC_HIDDEN__ extern _Atomic(size_t) __libc_tls_generation_copy;
struct TlsAlign {
@@ -214,30 +216,16 @@
};
#if defined(__i386__)
-#define TLS_GET_ADDR_CCONV __attribute__((regparm(1)))
+#define TLS_GET_ADDR_CALLING_CONVENTION __attribute__((regparm(1)))
#define TLS_GET_ADDR ___tls_get_addr
#else
-#define TLS_GET_ADDR_CCONV
+#define TLS_GET_ADDR_CALLING_CONVENTION
#define TLS_GET_ADDR __tls_get_addr
#endif
-extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CCONV;
+extern "C" void* TLS_GET_ADDR(const TlsIndex* ti) TLS_GET_ADDR_CALLING_CONVENTION;
struct bionic_tcb;
void __free_dynamic_tls(bionic_tcb* tcb);
void __notify_thread_exit_callbacks();
-#if defined(__riscv)
-// TLS_DTV_OFFSET is a constant used in relocation fields, defined in RISC-V ELF Specification[1]
-// The front of the TCB contains a pointer to the DTV, and each pointer in DTV
-// points to 0x800 past the start of a TLS block to make full use of the range
-// of load/store instructions, refer to [2].
-//
-// [1]: RISC-V ELF Specification.
-// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#constants
-// [2]: Documentation of TLS data structures
-// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/53
-#define TLS_DTV_OFFSET 0x800
-#else
-#define TLS_DTV_OFFSET 0
-#endif
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 23cd7f5..8adc342 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -26,15 +26,15 @@
// dlopen/dlclose.
static struct {
uintptr_t v;
- char padding[max_page_size() - sizeof(v)];
-} shadow_base_storage alignas(max_page_size());
+ char padding[max_android_page_size() - sizeof(v)];
+} shadow_base_storage alignas(max_android_page_size());
// __cfi_init is called by the loader as soon as the shadow is mapped. This may happen very early
// during startup, before libdl.so global constructors, and, on i386, even before __libc_sysinfo is
// initialized. This function should not do any system calls.
extern "C" uintptr_t* __cfi_init(uintptr_t shadow_base) {
shadow_base_storage.v = shadow_base;
- static_assert(sizeof(shadow_base_storage) == max_page_size(), "");
+ static_assert(sizeof(shadow_base_storage) == max_android_page_size(), "");
return &shadow_base_storage.v;
}
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 57b9d37..3627c84 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -281,11 +281,13 @@
if (!stack) {
async_safe_format_buffer(buf, sizeof(buf),
- "aborting due to fd leak: failed to find most common stack");
+ "aborting due to fd leak: see \"open files\" in the tombstone; "
+ "no stacks?!");
} else {
char* p = buf;
p += async_safe_format_buffer(buf, sizeof(buf),
- "aborting due to fd leak: most common stack =\n");
+ "aborting due to fd leak: see \"open files\" in the tombstone; "
+ "most common stack (%zu/%zu) is\n", max, stacks.count);
for (size_t i = 0; i < stack->stack_depth; ++i) {
ssize_t bytes_left = buf + sizeof(buf) - p;
diff --git a/linker/Android.bp b/linker/Android.bp
index e1a5a91..78109e8 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -231,6 +231,7 @@
name: "linker_sources_riscv64",
srcs: [
"arch/riscv64/begin.S",
+ "arch/riscv64/tlsdesc_resolver.S",
],
}
@@ -367,7 +368,9 @@
"liblinker_main",
"liblinker_malloc",
- "libc++_static",
+ // Use a version of libc++ built without exceptions, because accessing EH globals uses
+ // ELF TLS, which is not supported in the loader.
+ "libc++_static_noexcept",
"libc_nomalloc",
"libc_dynamic_dispatch",
"libm",
@@ -434,7 +437,7 @@
"linker_debuggerd_android.cpp",
],
static_libs: [
- "libc++demangle",
+ "libc++demangle_noexcept",
"libdebuggerd_handler_fallback",
],
},
diff --git a/linker/arch/riscv64/tlsdesc_resolver.S b/linker/arch/riscv64/tlsdesc_resolver.S
new file mode 100644
index 0000000..fedc926
--- /dev/null
+++ b/linker/arch/riscv64/tlsdesc_resolver.S
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2024 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 <platform/bionic/tls_defines.h>
+#include <private/bionic_asm.h>
+#include <private/bionic_elf_dtv_offset.h>
+
+#ifndef TLS_DTV_OFFSET
+ #error "TLS_DTV_OFFSET not defined"
+#endif
+
+.globl __tls_get_addr
+
+// spill a register onto the stack
+.macro spill reg, idx, f=
+ \f\()sd \reg, \idx*8(sp)
+ .cfi_rel_offset \reg, (\idx)*8
+.endm
+
+// reload a value from the stack
+.macro reload reg, idx, f=
+ \f\()ld \reg, \idx*8(sp)
+ .cfi_same_value \reg
+.endm
+
+.macro spill_vector_regs
+ csrr a3, vlenb
+ slli a3, a3, 3
+ sub sp, sp, a3
+ vs8r.v v0, (sp)
+ sub sp, sp, a3
+ vs8r.v v8, (sp)
+ sub sp, sp, a3
+ vs8r.v v16, (sp)
+ sub sp, sp, a3
+ vs8r.v v24, (sp)
+.endm
+
+.macro reload_vector_regs
+ csrr a3, vlenb
+ slli a3, a3, 3
+ vl8r.v v24, (sp)
+ add sp, sp, a3
+ vl8r.v v16, (sp)
+ add sp, sp, a3
+ vl8r.v v8, (sp)
+ add sp, sp, a3
+ vl8r.v v0, (sp)
+ add sp, sp, a3
+.endm
+
+// We save a total of 35 registers
+.macro for_each_saved_reg op max
+ \op ra, 1
+ \op a1, 2
+ \op a2, 3
+ \op a3, 4
+ \op a4, 5
+ \op a5, 6
+ \op a6, 7
+ \op a7, 8
+ \op t0, 9
+ \op t1, 10
+ \op t2, 11
+ \op t3, 12
+ \op t4, 13
+ \op t5, 14
+ \op t6, 15
+ // save floating point regs
+ \op ft0, 16, f
+ \op ft1, 17, f
+ \op ft2, 18, f
+ \op ft3, 19, f
+ \op ft4, 20, f
+ \op ft5, 21, f
+ \op ft6, 22, f
+ \op ft7, 23, f
+ \op ft8, 24, f
+ \op ft9, 25, f
+ \op ft10, 26, f
+ \op ft11, 27, f
+ \op fa0, 28, f
+ \op fa1, 29, f
+ \op fa2, 30, f
+ \op fa3, 31, f
+ \op fa4, 32, f
+ \op fa5, 33, f
+ \op fa6, 34, f
+ \op fa7, 35, f
+.endm
+
+// These resolver functions must preserve every register except a0. They set a0
+// to the offset of the TLS symbol relative to the thread pointer.
+
+ENTRY_PRIVATE(tlsdesc_resolver_static)
+ ld a0, 8(a0)
+ jr t0
+END(tlsdesc_resolver_static)
+
+ENTRY_PRIVATE(tlsdesc_resolver_dynamic)
+ // We only need 3 stack slots, but still require a 4th slot for alignment
+ addi sp, sp, -4*8
+ .cfi_def_cfa_offset 4*8
+ spill a1, 1
+ spill a2, 2
+ spill a3, 3
+
+ ld a2, (TLS_SLOT_DTV * 8)(tp) // a2 = &DTV
+ ld a1, (a2) // a1 = TlsDtv::generation (DTV[0])
+
+ ld a0, 8(a0) // a0 = TlsDynamicResolverArg*
+ ld a3, (a0) // a3 = TlsDynamicResolverArg::generation
+
+ // Fallback if TlsDtv::generation < TlsDynamicResolverArg::generation
+ // since we need to call __tls_get_addr
+ blt a1, a3, L(fallback)
+
+ // We can't modify a0 yet, since tlsdesc_resolver_dynamic_slow_path requires
+ // a pointer to the TlsIndex, which is the second field of the
+ // TlsDynamicResolverArg. As a result, we can't modify a0 until we will no
+ // longer fallback.
+ ld a1, 8(a0) // a1 = TlsIndex::module_id
+ slli a1, a1, 3 // a1 = module_id*8 -- scale the idx
+ add a1, a2, a1 // a1 = &TlsDtv::modules[module_id]
+ ld a1, (a1) // a1 = TlsDtv::modules[module_id]
+ beqz a1, L(fallback)
+ ld a3, 16(a0) // a3 = TlsIndex::offset
+ add a0, a1, a3 // a0 = TlsDtv::modules[module_id] + offset
+ sub a0, a0, tp // a0 = TlsDtv::modules[module_id] + offset - tp
+
+ .cfi_remember_state
+ reload a3, 3
+ reload a2, 2
+ reload a1, 1
+ addi sp, sp, 4*8
+ .cfi_adjust_cfa_offset -4*8
+ jr t0
+
+L(fallback):
+ reload a3, 3
+ reload a2, 2
+ reload a1, 1
+ addi sp, sp, 4*8
+ .cfi_adjust_cfa_offset -4*8
+ j tlsdesc_resolver_dynamic_slow_path
+END(tlsdesc_resolver_dynamic)
+
+// On entry, a0 is the address of a TlsDynamicResolverArg object rather than
+// the TlsDescriptor address passed to the original resolver function.
+ENTRY_PRIVATE(tlsdesc_resolver_dynamic_slow_path)
+ // We save a total of 35 registers, but vector spills require an alignment
+ // of 16, so use an extra slot to align it correctly.
+ addi sp, sp, (-8*36)
+ .cfi_def_cfa_offset (8 * 36)
+ for_each_saved_reg spill, 36
+ spill_vector_regs
+
+ add a0, a0, 8
+ call __tls_get_addr
+ addi a0, a0, (-1 * TLS_DTV_OFFSET) // Correct the address by TLS_DTV_OFFSET
+ sub a0, a0, tp
+
+ reload_vector_regs
+ for_each_saved_reg reload, 36
+ addi sp, sp, 8*36
+ .cfi_def_cfa_offset 0
+ jr t0
+END(tlsdesc_resolver_dynamic_slow_path)
+
+// The address of an unresolved weak TLS symbol evaluates to NULL with TLSDESC.
+// The value returned by this function is added to the thread pointer, so return
+// a negated thread pointer to cancel it out.
+ENTRY_PRIVATE(tlsdesc_resolver_unresolved_weak)
+ sub a0, zero, tp
+ jr t0
+END(tlsdesc_resolver_unresolved_weak)
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index e27fd91..2b230a8 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -31,6 +31,7 @@
#include <link.h>
#include <stdlib.h>
#include <sys/auxv.h>
+#include <sys/prctl.h>
#include "linker.h"
#include "linker_auxv.h"
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 85f7b3a..3e36114 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -438,9 +438,9 @@
}
break;
-#if defined(__aarch64__)
- // Bionic currently only implements TLSDESC for arm64. This implementation should work with
- // other architectures, as long as the resolver functions are implemented.
+#if defined(__aarch64__) || defined(__riscv)
+ // Bionic currently implements TLSDESC for arm64 and riscv64. This implementation should work
+ // with other architectures, as long as the resolver functions are implemented.
case R_GENERIC_TLSDESC:
count_relocation_if<IsGeneral>(kRelocRelative);
{
@@ -482,7 +482,7 @@
}
}
break;
-#endif // defined(__aarch64__)
+#endif // defined(__aarch64__) || defined(__riscv)
#if defined(__x86_64__)
case R_X86_64_32:
@@ -672,14 +672,14 @@
// Once the tlsdesc_args_ vector's size is finalized, we can write the addresses of its elements
// into the TLSDESC relocations.
-#if defined(__aarch64__)
- // Bionic currently only implements TLSDESC for arm64.
+#if defined(__aarch64__) || defined(__riscv)
+ // Bionic currently only implements TLSDESC for arm64 and riscv64.
for (const std::pair<TlsDescriptor*, size_t>& pair : relocator.deferred_tlsdesc_relocs) {
TlsDescriptor* desc = pair.first;
desc->func = tlsdesc_resolver_dynamic;
desc->arg = reinterpret_cast<size_t>(&tlsdesc_args_[pair.second]);
}
-#endif
+#endif // defined(__aarch64__) || defined(__riscv)
return true;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 528ccb8..9aca488 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1136,11 +1136,14 @@
shared_libs: [
"libbase",
],
- data_libs: ["libtest_simple_memtag_stack", "libtest_depends_on_simple_memtag_stack"],
+ data_libs: [
+ "libtest_simple_memtag_stack",
+ "libtest_depends_on_simple_memtag_stack",
+ ],
data_bins: [
"testbinary_depends_on_simple_memtag_stack",
"testbinary_depends_on_depends_on_simple_memtag_stack",
- "testbinary_is_stack_mte_after_dlopen"
+ "testbinary_is_stack_mte_after_dlopen",
],
header_libs: ["bionic_libc_platform_headers"],
test_suites: ["device-tests"],
@@ -1315,4 +1318,47 @@
},
}
-subdirs = ["*"]
+cc_defaults {
+ name: "bionic_compile_time_tests_defaults",
+ enabled: false,
+ target: {
+ linux_x86: {
+ enabled: true,
+ },
+ linux_x86_64: {
+ enabled: true,
+ },
+ },
+ tidy: false,
+ clang_verify: true,
+ cflags: [
+ "-Wall",
+ "-Wno-error",
+ "-fno-color-diagnostics",
+ "-ferror-limit=10000",
+ "-DCOMPILATION_TESTS=1",
+ "-Wformat-nonliteral",
+ "-U_FORTIFY_SOURCE",
+ ],
+ srcs: ["clang_fortify_tests.cpp"],
+}
+
+cc_library_static {
+ name: "bionic-compile-time-tests1-clang++",
+ defaults: [
+ "bionic_compile_time_tests_defaults",
+ ],
+ cppflags: [
+ "-D_FORTIFY_SOURCE=1",
+ ],
+}
+
+cc_library_static {
+ name: "bionic-compile-time-tests2-clang++",
+ defaults: [
+ "bionic_compile_time_tests_defaults",
+ ],
+ cppflags: [
+ "-D_FORTIFY_SOURCE=2",
+ ],
+}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 5ad4045..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-
-# -----------------------------------------------------------------------------
-# Compile time tests.
-# -----------------------------------------------------------------------------
-
-FORTIFY_LEVEL := 1
-include $(LOCAL_PATH)/make_fortify_compile_test.mk
-
-FORTIFY_LEVEL := 2
-include $(LOCAL_PATH)/make_fortify_compile_test.mk
-
-endif # linux-x86
-
-include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 6a1831f..8fdb2b2 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -32,7 +32,11 @@
#include <math.h> // For M_PI_2/M_PI_2l.
// Prettify gtest Complex printing.
+// Macro 'complex' defined in complex.h conflicts with iostream.
+#pragma push_macro("complex")
+#undef complex
#include <iostream>
+#pragma pop_macro("complex")
namespace testing {
namespace internal {
inline void PrintTo(const double _Complex& c, std::ostream* os) {
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index e759e15..e409b72 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -107,6 +107,22 @@
void* lib = dlopen("libtest_elftls_dynamic.so", RTLD_LOCAL | RTLD_NOW);
ASSERT_NE(nullptr, lib);
+ auto get_local_var2 = reinterpret_cast<int(*)()>(dlsym(lib, "get_local_var2"));
+ ASSERT_NE(nullptr, get_local_var2);
+
+ auto get_local_var1 = reinterpret_cast<int(*)()>(dlsym(lib, "get_local_var1"));
+ ASSERT_NE(nullptr, get_local_var1);
+
+ auto get_local_var1_addr = reinterpret_cast<int*(*)()>(dlsym(lib, "get_local_var1_addr"));
+ ASSERT_NE(nullptr, get_local_var1_addr);
+
+ // Make sure subsequent accesses return the same pointer.
+ ASSERT_EQ(get_local_var1_addr(), get_local_var1_addr());
+
+ // Check the initial values are correct.
+ ASSERT_EQ(25, get_local_var2());
+ ASSERT_EQ(15, get_local_var1());
+
auto bump_local_vars = reinterpret_cast<int(*)()>(dlsym(lib, "bump_local_vars"));
ASSERT_NE(nullptr, bump_local_vars);
@@ -135,7 +151,7 @@
// TLSDESC, the result is NULL. With __tls_get_addr, the result is the
// generation count (or maybe undefined behavior)? This test only tests TLSDESC.
TEST(elftls_dl, tlsdesc_missing_weak) {
-#if defined(__aarch64__)
+#if defined(__aarch64__) || defined(__riscv)
void* lib = dlopen("libtest_elftls_dynamic.so", RTLD_LOCAL | RTLD_NOW);
ASSERT_NE(nullptr, lib);
diff --git a/tests/libs/elftls_dtv_resize_helper.cpp b/tests/libs/elftls_dtv_resize_helper.cpp
index 340d5df..7fb6fb5 100644
--- a/tests/libs/elftls_dtv_resize_helper.cpp
+++ b/tests/libs/elftls_dtv_resize_helper.cpp
@@ -180,8 +180,8 @@
// Access a TLS variable from the first filler module.
ASSERT_EQ(102, func1());
ASSERT_EQ(5u, highest_modid_in_dtv());
-#if defined(__aarch64__)
- // The arm64 TLSDESC resolver doesn't update the DTV if it is new enough for
+#if defined(__aarch64__) || defined(__riscv)
+ // The arm64 and riscv64 TLSDESC resolver doesn't update the DTV if it is new enough for
// the given access.
ASSERT_EQ(initial_dtv, dtv());
ASSERT_EQ(5u, dtv()->count);
diff --git a/tests/libs/elftls_dynamic.cpp b/tests/libs/elftls_dynamic.cpp
index 2500484..df3ad75 100644
--- a/tests/libs/elftls_dynamic.cpp
+++ b/tests/libs/elftls_dynamic.cpp
@@ -66,6 +66,18 @@
return ++local_var_1 + ++local_var_2;
}
+extern "C" int get_local_var1() {
+ return local_var_1;
+}
+
+extern "C" int* get_local_var1_addr() {
+ return &local_var_1;
+}
+
+extern "C" int get_local_var2() {
+ return local_var_2;
+}
+
__attribute__((weak)) extern "C" __thread int missing_weak_dyn_tls;
extern "C" int* missing_weak_dyn_tls_addr() {
diff --git a/tests/make_fortify_compile_test.mk b/tests/make_fortify_compile_test.mk
deleted file mode 100644
index ec0ba45..0000000
--- a/tests/make_fortify_compile_test.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-include $(CLEAR_VARS)
-
-LOCAL_ADDITIONAL_DEPENDENCIES := \
- $(LOCAL_PATH)/Android.mk \
- $(LOCAL_PATH)/touch-obj-on-success
-
-LOCAL_CXX := $(LOCAL_PATH)/touch-obj-on-success \
- $(LLVM_PREBUILTS_PATH)/clang++ \
-
-LOCAL_CLANG := true
-LOCAL_MODULE := bionic-compile-time-tests$(FORTIFY_LEVEL)-clang++
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
-LOCAL_TIDY := false
-LOCAL_CPPFLAGS := -Wall -Wno-error
-LOCAL_CPPFLAGS += -fno-color-diagnostics -ferror-limit=10000 -Xclang -verify
-LOCAL_CPPFLAGS += -DCOMPILATION_TESTS=1 -Wformat-nonliteral
-LOCAL_CPPFLAGS += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=$(FORTIFY_LEVEL)
-LOCAL_SRC_FILES := clang_fortify_tests.cpp
-
-include $(BUILD_STATIC_LIBRARY)
-
-FORTIFY_LEVEL :=
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index 0de0a01..9469285 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -174,6 +174,9 @@
}
}
+#if defined(__arm__) || defined(__aarch64__)
+// arm and arm64 have the same callee save fp registers (8-15),
+// but use different instructions for accessing them.
#if defined(__arm__)
#define SET_FREG(n, v) asm volatile("vmov.f64 d"#n ", #"#v : : : "d"#n)
#define GET_FREG(n) ({ double _r; asm volatile("fcpyd %P0, d"#n : "=w"(_r) : :); _r;})
@@ -183,21 +186,53 @@
#define GET_FREG(n) ({ double _r; asm volatile("fmov %0, d"#n : "=r"(_r) : :); _r; })
#define CLEAR_FREG(n) asm volatile("fmov d"#n ", xzr" : : : "d"#n)
#endif
-
-#if defined(__arm__) || defined(__aarch64__)
#define SET_FREGS \
SET_FREG(8, 8.0); SET_FREG(9, 9.0); SET_FREG(10, 10.0); SET_FREG(11, 11.0); \
- SET_FREG(12, 12.0); SET_FREG(13, 13.0); SET_FREG(14, 14.0); SET_FREG(15, 15.0);
+ SET_FREG(12, 12.0); SET_FREG(13, 13.0); SET_FREG(14, 14.0); SET_FREG(15, 15.0)
#define CLEAR_FREGS \
CLEAR_FREG(8); CLEAR_FREG(9); CLEAR_FREG(10); CLEAR_FREG(11); \
- CLEAR_FREG(12); CLEAR_FREG(13); CLEAR_FREG(14); CLEAR_FREG(15);
+ CLEAR_FREG(12); CLEAR_FREG(13); CLEAR_FREG(14); CLEAR_FREG(15)
#define CHECK_FREGS \
- EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \
- EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \
- EXPECT_EQ(12.0, GET_FREG(12)); EXPECT_EQ(13.0, GET_FREG(13)); \
- EXPECT_EQ(14.0, GET_FREG(14)); EXPECT_EQ(15.0, GET_FREG(15));
+ EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \
+ EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \
+ EXPECT_EQ(12.0, GET_FREG(12)); EXPECT_EQ(13.0, GET_FREG(13)); \
+ EXPECT_EQ(14.0, GET_FREG(14)); EXPECT_EQ(15.0, GET_FREG(15))
+
+#elif defined(__riscv)
+// riscv64 has callee save registers fs0-fs11.
+// TODO: use Zfa to get 1.0 rather than the one_p trick.
+#define SET_FREGS \
+ double one = 1, *one_p = &one; \
+ asm volatile("fmv.d.x fs0, zero ; fld fs1, (%0) ; \
+ fadd.d fs2, fs1, fs1 ; fadd.d fs3, fs2, fs1 ; \
+ fadd.d fs4, fs3, fs1 ; fadd.d fs5, fs4, fs1 ; \
+ fadd.d fs6, fs5, fs1 ; fadd.d fs7, fs6, fs1 ; \
+ fadd.d fs8, fs7, fs1 ; fadd.d fs9, fs8, fs1 ; \
+ fadd.d fs10, fs9, fs1 ; fadd.d fs11, fs10, fs1" \
+ : \
+ : "r"(one_p) \
+ : "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", \
+ "fs6", "fs7", "fs8", "fs9", "fs10", "fs11")
+#define CLEAR_FREGS \
+ asm volatile("fmv.d.x fs0, zero ; fmv.d.x fs1, zero ; \
+ fmv.d.x fs2, zero ; fmv.d.x fs3, zero ; \
+ fmv.d.x fs4, zero ; fmv.d.x fs5, zero ; \
+ fmv.d.x fs6, zero ; fmv.d.x fs7, zero ; \
+ fmv.d.x fs8, zero ; fmv.d.x fs9, zero ; \
+ fmv.d.x fs10, zero ; fmv.d.x fs11, zero" \
+ : : : "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", \
+ "fs6", "fs7", "fs8", "fs9", "fs10", "fs11")
+#define GET_FREG(n) ({ double _r; asm volatile("fmv.d %0, fs"#n : "=f"(_r) : :); _r; })
+#define CHECK_FREGS \
+ EXPECT_EQ(0.0, GET_FREG(0)); EXPECT_EQ(1.0, GET_FREG(1)); \
+ EXPECT_EQ(2.0, GET_FREG(2)); EXPECT_EQ(3.0, GET_FREG(3)); \
+ EXPECT_EQ(4.0, GET_FREG(4)); EXPECT_EQ(5.0, GET_FREG(5)); \
+ EXPECT_EQ(6.0, GET_FREG(6)); EXPECT_EQ(7.0, GET_FREG(7)); \
+ EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \
+ EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11))
+
#else
-/* The other architectures don't save/restore fp registers. */
+// x86 and x86-64 don't save/restore fp registers.
#define SET_FREGS
#define CLEAR_FREGS
#define CHECK_FREGS
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index 5cb634c..7cdfa42 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -121,9 +121,10 @@
EXPECT_SWPRINTF_N(expected, static_cast<int>(wcslen(expected)), fmt __VA_OPT__(, ) __VA_ARGS__)
TEST(STDIO_TEST, flockfile_18208568_stderr) {
- // Check that we have a _recursive_ mutex for flockfile.
flockfile(stderr);
- feof(stderr); // We don't care about the result, but this needs to take the lock.
+ // Check that we're using a _recursive_ mutex for flockfile() by calling
+ // something that will take the lock.
+ ASSERT_EQ(0, feof(stderr));
funlockfile(stderr);
}
@@ -132,7 +133,9 @@
FILE* fp = fopen("/dev/null", "w");
ASSERT_TRUE(fp != nullptr);
flockfile(fp);
- feof(fp);
+ // Check that we're using a _recursive_ mutex for flockfile() by calling
+ // something that will take the lock.
+ ASSERT_EQ(0, feof(fp));
funlockfile(fp);
fclose(fp);
}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index ca8e260..baafbf6 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -31,6 +31,8 @@
#include <thread>
#include "SignalUtils.h"
+#include "android-base/file.h"
+#include "android-base/strings.h"
#include "utils.h"
using namespace std::chrono_literals;
@@ -797,21 +799,41 @@
ASSERT_EQ(1, timer_create_NULL_signal_handler_invocation_count);
}
-TEST(time, timer_create_EINVAL) {
- clockid_t invalid_clock = 16;
+static int GetThreadCount() {
+ std::string status;
+ if (android::base::ReadFileToString("/proc/self/status", &status)) {
+ for (const auto& line : android::base::Split(status, "\n")) {
+ int thread_count;
+ if (sscanf(line.c_str(), "Threads: %d", &thread_count) == 1) {
+ return thread_count;
+ }
+ }
+ }
+ return -1;
+}
- // A SIGEV_SIGNAL timer is easy; the kernel does all that.
+TEST(time, timer_create_EINVAL) {
+ const clockid_t kInvalidClock = 16;
+
+ // A SIGEV_SIGNAL timer failure is easy; that's the kernel's problem.
timer_t timer_id;
- ASSERT_EQ(-1, timer_create(invalid_clock, nullptr, &timer_id));
+ ASSERT_EQ(-1, timer_create(kInvalidClock, nullptr, &timer_id));
ASSERT_ERRNO(EINVAL);
- // A SIGEV_THREAD timer is more interesting because we have stuff to clean up.
- sigevent se;
- memset(&se, 0, sizeof(se));
+ // A SIGEV_THREAD timer failure is more interesting because we have a thread
+ // to clean up (https://issuetracker.google.com/340125671).
+ sigevent se = {};
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = NoOpNotifyFunction;
- ASSERT_EQ(-1, timer_create(invalid_clock, &se, &timer_id));
+ ASSERT_EQ(-1, timer_create(kInvalidClock, &se, &timer_id));
ASSERT_ERRNO(EINVAL);
+
+ // timer_create() doesn't guarantee that the thread will be dead _before_
+ // it returns because that would require extra synchronization that's
+ // unnecessary in the normal (successful) case. A timeout here means we
+ // leaked a thread.
+ while (GetThreadCount() > 1) {
+ }
}
TEST(time, timer_create_multiple) {
diff --git a/tests/utils.h b/tests/utils.h
index dcb08f5..3c83b73 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -38,6 +38,7 @@
#endif
#include <atomic>
+#include <iomanip>
#include <string>
#include <regex>
@@ -253,7 +254,7 @@
AssertChildExited(pid, expected_exit_status, &error_msg);
if (expected_output_regex != nullptr) {
if (!std::regex_search(output_, std::regex(expected_output_regex))) {
- FAIL() << "regex " << expected_output_regex << " didn't match " << output_;
+ FAIL() << "regex " << std::quoted(expected_output_regex) << " didn't match " << std::quoted(output_);
}
}
}
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index 5256b08..387d23b 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -1075,10 +1075,39 @@
EXPECT_EQ(0, wcwidth(0x0300)); // Combining grave.
EXPECT_EQ(0, wcwidth(0x20dd)); // Combining enclosing circle.
- EXPECT_EQ(0, wcwidth(0x00ad)); // Soft hyphen (SHY).
EXPECT_EQ(0, wcwidth(0x200b)); // Zero width space.
}
+TEST(wchar, wcwidth_non_spacing_special_cases) {
+ if (!have_dl()) return;
+
+ // U+00AD is a soft hyphen, which normally shouldn't be rendered at all.
+ // I think the assumption here is that you elide the soft hyphen character
+ // completely in that case, and never call wcwidth() if you don't want to
+ // render it as an actual hyphen. Whereas if you do want to render it,
+ // you call wcwidth(), and 1 is the right answer. This is what Markus Kuhn's
+ // original https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c did,
+ // and glibc and iOS do the same.
+ // See also: https://en.wikipedia.org/wiki/Soft_hyphen#Text_to_be_formatted_by_the_recipient
+ EXPECT_EQ(1, wcwidth(0x00ad)); // Soft hyphen (SHY).
+
+ // U+115F is the Hangeul choseong filler (for a degenerate composed
+ // character missing an initial consonant (as opposed to one with a
+ // leading ieung). Since the code points for combining jungseong (medial
+ // vowels) and jongseong (trailing consonants) have width 0, the choseong
+ // (initial consonant) has width 2 to cover the entire syllable. So unless
+ // U+115f has width 2, a degenerate composed "syllable" without an initial
+ // consonant or ieung would have a total width of 0, which is silly.
+ // The following sequence is effectively "약" without the leading ieung...
+ EXPECT_EQ(2, wcwidth(0x115f)); // Hangeul choseong filler.
+ EXPECT_EQ(0, wcwidth(0x1163)); // Hangeul jungseong "ya".
+ EXPECT_EQ(0, wcwidth(0x11a8)); // Hangeul jongseong "kiyeok".
+
+ // U+1160, the jungseong filler, has width 0 because it must have been
+ // preceded by either a choseong or choseong filler.
+ EXPECT_EQ(0, wcwidth(0x1160));
+}
+
TEST(wchar, wcwidth_cjk) {
if (!have_dl()) return;
@@ -1102,8 +1131,10 @@
if (!have_dl()) return;
EXPECT_EQ(2, wcwidth(0xac00)); // Start of block.
- EXPECT_EQ(2, wcwidth(0xd7a3)); // End of defined code points in Unicode 7.
- // Undefined characters at the end of the block have width 1.
+ EXPECT_EQ(2, wcwidth(0xd7a3)); // End of defined code points as of Unicode 15.
+
+ // Undefined characters at the end of the block currently have width 1,
+ // but since they're undefined, we don't test that.
}
TEST(wchar, wcwidth_kana) {
@@ -1137,11 +1168,21 @@
EXPECT_EQ(0, wcwidth(0xe0000)); // ...through 0xe0fff.
}
-TEST(wchar, wcwidth_korean_common_non_syllables) {
+TEST(wchar, wcwidth_hangeul_compatibility_jamo) {
if (!have_dl()) return;
- EXPECT_EQ(2, wcwidth(L'ㅜ')); // Korean "crying" emoticon.
- EXPECT_EQ(2, wcwidth(L'ㅋ')); // Korean "laughing" emoticon.
+ // These are actually the *compatibility* jamo code points, *not* the regular
+ // jamo code points (U+1100-U+11FF) using a jungseong filler. If you use the
+ // Android IME to type any of these, you get these code points.
+
+ // (Half of) the Korean "crying" emoticon "ㅠㅠ".
+ // Actually U+3160 "Hangeul Letter Yu" from Hangeul Compatibility Jamo.
+ EXPECT_EQ(2, wcwidth(L'ㅠ'));
+ // The two halves of the Korean internet shorthand "ㄱㅅ" (short for 감사).
+ // Actually U+3131 "Hangeul Letter Kiyeok" and U+3145 "Hangeul Letter Sios"
+ // from Hangeul Compatibility Jamo.
+ EXPECT_EQ(2, wcwidth(L'ㄱ'));
+ EXPECT_EQ(2, wcwidth(L'ㅅ'));
}
TEST(wchar, wcswidth) {