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