Merge "Improve pty unit test to catch the bug more easily."
diff --git a/libc/Android.bp b/libc/Android.bp
index 39bd2ec..69eba45 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1538,7 +1538,6 @@
"bionic/sys_time.cpp",
"bionic/sysinfo.cpp",
"bionic/syslog.cpp",
- "bionic/system_properties.cpp",
"bionic/tdestroy.cpp",
"bionic/termios.cpp",
"bionic/thread_private.cpp",
@@ -1552,6 +1551,12 @@
"bionic/wctype.cpp",
"bionic/wcwidth.cpp",
"bionic/wmempcpy.cpp",
+ "system_properties/context_node.cpp",
+ "system_properties/contexts_split.cpp",
+ "system_properties/prop_area.cpp",
+ "system_properties/prop_info.cpp",
+ "system_properties/system_properties.cpp",
+
// This contains a weak stub implementation of __find_icu_symbol for wctype.cpp,
// which will be overridden by the actual one in libc.so.
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 50fcbce..43a5032 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -195,6 +195,89 @@
return NULL;
}
+// These are a list of the reserved app ranges, and should never contain anything below
+// AID_APP_START. They exist per user, so a given uid/gid modulo AID_USER_OFFSET will map
+// to these ranges.
+static constexpr struct {
+ uid_t start;
+ uid_t end;
+} user_ranges[] = {
+ { AID_APP_START, AID_APP_END },
+ { AID_CACHE_GID_START, AID_CACHE_GID_END },
+ { AID_EXT_GID_START, AID_EXT_GID_END },
+ { AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END },
+ { AID_SHARED_GID_START, AID_SHARED_GID_END },
+ { AID_ISOLATED_START, AID_ISOLATED_END },
+};
+
+static constexpr bool verify_user_ranges_ascending() {
+ auto array_size = arraysize(user_ranges);
+ if (array_size < 2) return false;
+
+ if (user_ranges[0].start > user_ranges[0].end) return false;
+
+ for (size_t i = 1; i < array_size; ++i) {
+ if (user_ranges[i].start > user_ranges[i].end) return false;
+ if (user_ranges[i - 1].end > user_ranges[i].start) return false;
+ }
+ return true;
+}
+
+static_assert(verify_user_ranges_ascending(), "user_ranges must have ascending ranges");
+
+static bool is_valid_app_id(id_t id) {
+ id_t appid = id % AID_USER_OFFSET;
+
+ // AID_OVERFLOWUID is never a valid app id, so we explicitly return false to ensure this.
+ // This is true across all users, as there is no reason to ever map this id into any user range.
+ if (appid == AID_OVERFLOWUID) {
+ return false;
+ }
+
+ // If we've resolved to something before app_start, we have already checked against
+ // android_ids, so no need to check again.
+ if (appid < user_ranges[0].start) {
+ return true;
+ }
+
+ // Otherwise check that the appid is in one of the reserved ranges.
+ for (size_t i = 0; i < arraysize(user_ranges); ++i) {
+ if (appid >= user_ranges[i].start && appid <= user_ranges[i].end) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// This provides an iterater for app_ids within the first user's app id's.
+static uid_t get_next_app_id(uid_t current_id) {
+ // If current_id is below the first of the user_ranges, then we're uninitialized, and return the
+ // first valid id.
+ if (current_id < user_ranges[0].start) {
+ return user_ranges[0].start;
+ }
+
+ uid_t incremented_id = current_id + 1;
+
+ // Check to see if our incremented_id is between two ranges, and if so, return the beginning of
+ // the next valid range.
+ for (size_t i = 1; i < arraysize(user_ranges); ++i) {
+ if (incremented_id > user_ranges[i - 1].end && incremented_id < user_ranges[i].start) {
+ return user_ranges[i].start;
+ }
+ }
+
+ // Check to see if our incremented_id is above final range, and return -1 to indicate that we've
+ // completed if so.
+ if (incremented_id > user_ranges[arraysize(user_ranges) - 1].end) {
+ return -1;
+ }
+
+ // Otherwise the incremented_id is valid, so return it.
+ return incremented_id;
+}
+
// Translate a user/group name to the corresponding user/group id.
// all_a1234 -> 0 * AID_USER_OFFSET + AID_SHARED_GID_START + 1234 (group name only)
// u0_a1234_cache -> 0 * AID_USER_OFFSET + AID_CACHE_GID_START + 1234 (group name only)
@@ -377,7 +460,7 @@
// AID_USER_OFFSET+ -> u1_radio, u1_a1234, u2_i1234, etc.
// returns a passwd structure (sets errno to ENOENT on failure).
static passwd* app_id_to_passwd(uid_t uid, passwd_state_t* state) {
- if (uid < AID_APP_START) {
+ if (uid < AID_APP_START || !is_valid_app_id(uid)) {
errno = ENOENT;
return NULL;
}
@@ -405,7 +488,7 @@
// Translate a gid into the corresponding app_<gid>
// group structure (sets errno to ENOENT on failure).
static group* app_id_to_group(gid_t gid, group_state_t* state) {
- if (gid < AID_APP_START) {
+ if (gid < AID_APP_START || !is_valid_app_id(gid)) {
errno = ENOENT;
return NULL;
}
@@ -521,15 +604,13 @@
state->getpwent_idx++ - start + AID_OEM_RESERVED_2_START, state);
}
- start = end;
- end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher users
+ state->getpwent_idx = get_next_app_id(state->getpwent_idx);
- if (state->getpwent_idx < end) {
- return app_id_to_passwd(state->getpwent_idx++ - start + AID_APP_START, state);
+ if (state->getpwent_idx != -1) {
+ return app_id_to_passwd(state->getpwent_idx, state);
}
// We are not reporting u1_a* and higher or we will be here forever
- state->getpwent_idx = -1;
return NULL;
}
@@ -652,12 +733,12 @@
start = end;
end += AID_USER_OFFSET - AID_APP_START; // Do not expose higher groups
- if (state->getgrent_idx < end) {
- init_group_state(state);
- return app_id_to_group(state->getgrent_idx++ - start + AID_APP_START, state);
+ state->getgrent_idx = get_next_app_id(state->getgrent_idx);
+
+ if (state->getgrent_idx != -1) {
+ return app_id_to_group(state->getgrent_idx, state);
}
// We are not reporting u1_a* and higher or we will be here forever
- state->getgrent_idx = -1;
return NULL;
}
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index 3588d02..061d68c 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -91,19 +91,13 @@
sigset_t sigdefault;
void Do() {
- bool use_sigdefault = ((flags & POSIX_SPAWN_SETSIGDEF) != 0);
-
- for (int s = 1; s < _NSIG; ++s) {
- struct sigaction sa;
- if (sigaction(s, nullptr, &sa) == -1) _exit(127);
- if (sa.sa_handler == SIG_DFL) continue;
- // POSIX: "Signals set to be caught by the calling process shall be set to the default
- // action in the child process."
+ if ((flags & POSIX_SPAWN_SETSIGDEF) != 0) {
// POSIX: "If POSIX_SPAWN_SETSIGDEF is set ... signals in sigdefault ... shall be set to
// their default actions in the child process."
- if (sa.sa_handler != SIG_IGN || (use_sigdefault && sigismember(&sigdefault, s))) {
- sa.sa_handler = SIG_DFL;
- if (sigaction(s, &sa, nullptr) == -1) _exit(127);
+ struct sigaction sa = {};
+ sa.sa_handler = SIG_DFL;
+ for (int s = 1; s < _NSIG; ++s) {
+ if (sigismember(&sigdefault, s) && sigaction(s, &sa, nullptr) == -1) _exit(127);
}
}
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index d45cb38..2442fd9 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -52,9 +52,16 @@
// Things we actually have to calculate...
//
case _SC_ARG_MAX:
- // Not a constant since Linux 2.6.23; see fs/exec.c for details.
- // At least 32 pages, otherwise a quarter of the stack limit.
- return MAX(__sysconf_rlimit(RLIMIT_STACK) / 4, _KERNEL_ARG_MAX);
+ // https://lkml.org/lkml/2017/11/15/813...
+ //
+ // I suspect a 128kB sysconf(_SC_ARG_MAX) is the sanest bet, simply
+ // because of that "conservative is better than aggressive".
+ //
+ // Especially since _technically_ we're still limiting things to that
+ // 128kB due to the single-string limit.
+ //
+ // Linus
+ return ARG_MAX;
case _SC_AVPHYS_PAGES: return get_avphys_pages();
case _SC_CHILD_MAX: return __sysconf_rlimit(RLIMIT_NPROC);
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
deleted file mode 100644
index 1a7a359..0000000
--- a/libc/bionic/system_properties.cpp
+++ /dev/null
@@ -1,1574 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <stdatomic.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <new>
-
-#include <linux/xattr.h>
-#include <netinet/in.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/un.h>
-#include <sys/xattr.h>
-
-#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
-#include <sys/_system_properties.h>
-#include <sys/system_properties.h>
-
-#include <async_safe/log.h>
-
-#include "private/ErrnoRestorer.h"
-#include "private/bionic_defs.h"
-#include "private/bionic_futex.h"
-#include "private/bionic_lock.h"
-#include "private/bionic_macros.h"
-#include "private/bionic_sdk_version.h"
-
-static constexpr int PROP_FILENAME_MAX = 1024;
-
-static constexpr uint32_t PROP_AREA_MAGIC = 0x504f5250;
-static constexpr uint32_t PROP_AREA_VERSION = 0xfc6ed0ab;
-
-static constexpr size_t PA_SIZE = 128 * 1024;
-
-#define SERIAL_DIRTY(serial) ((serial)&1)
-#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
-
-constexpr static const char kLongLegacyError[] = "Must use __system_property_read_callback() to read";
-
-// The error message fits in part of a union with the previous 92 char property value so there must
-// be room left over after the error message for the offset to the new longer property value and
-// future expansion fields if needed.
-// Note that this value cannot ever increase. The offset to the new longer property value appears
-// immediately after it, so an increase of this size will break compatibility.
-constexpr size_t kLongLegacyErrorBufferSize = 56;
-static_assert(sizeof(kLongLegacyError) < kLongLegacyErrorBufferSize,
- "Error message for long properties read by legacy libc must fit within 56 chars");
-
-static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
-static const char* kServiceVersionPropertyName = "ro.property_service.version";
-
-// The C11 standard doesn't allow atomic loads from const fields,
-// though C++11 does. Fudge it until standards get straightened out.
-static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, memory_order mo) {
- atomic_uint_least32_t* non_const_s = const_cast<atomic_uint_least32_t*>(s);
- return atomic_load_explicit(non_const_s, mo);
-}
-
-/*
- * Properties are stored in a hybrid trie/binary tree structure.
- * Each property's name is delimited at '.' characters, and the tokens are put
- * into a trie structure. Siblings at each level of the trie are stored in a
- * binary tree. For instance, "ro.secure"="1" could be stored as follows:
- *
- * +-----+ children +----+ children +--------+
- * | |-------------->| ro |-------------->| secure |
- * +-----+ +----+ +--------+
- * / \ / |
- * left / \ right left / | prop +===========+
- * v v v +-------->| ro.secure |
- * +-----+ +-----+ +-----+ +-----------+
- * | net | | sys | | com | | 1 |
- * +-----+ +-----+ +-----+ +===========+
- */
-
-// Represents a node in the trie.
-struct prop_bt {
- uint32_t namelen;
-
- // The property trie is updated only by the init process (single threaded) which provides
- // property service. And it can be read by multiple threads at the same time.
- // As the property trie is not protected by locks, we use atomic_uint_least32_t types for the
- // left, right, children "pointers" in the trie node. To make sure readers who see the
- // change of "pointers" can also notice the change of prop_bt structure contents pointed by
- // the "pointers", we always use release-consume ordering pair when accessing these "pointers".
-
- // prop "points" to prop_info structure if there is a propery associated with the trie node.
- // Its situation is similar to the left, right, children "pointers". So we use
- // atomic_uint_least32_t and release-consume ordering to protect it as well.
-
- // We should also avoid rereading these fields redundantly, since not
- // all processor implementations ensure that multiple loads from the
- // same field are carried out in the right order.
- atomic_uint_least32_t prop;
-
- atomic_uint_least32_t left;
- atomic_uint_least32_t right;
-
- atomic_uint_least32_t children;
-
- char name[0];
-
- prop_bt(const char* name, const uint32_t name_length) {
- this->namelen = name_length;
- memcpy(this->name, name, name_length);
- this->name[name_length] = '\0';
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(prop_bt);
-};
-
-class prop_area {
- public:
- prop_area(const uint32_t magic, const uint32_t version) : magic_(magic), version_(version) {
- atomic_init(&serial_, 0);
- memset(reserved_, 0, sizeof(reserved_));
- // Allocate enough space for the root node.
- bytes_used_ = sizeof(prop_bt);
- }
-
- const prop_info* find(const char* name);
- bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
-
- bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
-
- atomic_uint_least32_t* serial() {
- return &serial_;
- }
- uint32_t magic() const {
- return magic_;
- }
- uint32_t version() const {
- return version_;
- }
-
- private:
- void* allocate_obj(const size_t size, uint_least32_t* const off);
- prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off);
- prop_info* new_prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen,
- uint_least32_t* const off);
- void* to_prop_obj(uint_least32_t off);
- prop_bt* to_prop_bt(atomic_uint_least32_t* off_p);
- prop_info* to_prop_info(atomic_uint_least32_t* off_p);
-
- prop_bt* root_node();
-
- prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed);
-
- const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
- const char* value, uint32_t valuelen, bool alloc_if_needed);
-
- bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
- void* cookie);
-
- uint32_t bytes_used_;
- atomic_uint_least32_t serial_;
- uint32_t magic_;
- uint32_t version_;
- uint32_t reserved_[28];
- char data_[0];
-
- DISALLOW_COPY_AND_ASSIGN(prop_area);
-};
-
-struct prop_info {
- // Read only properties will not set anything but the bottom most bit of serial and the top byte.
- // We borrow the 2nd from the top byte for extra flags, and use the bottom most bit of that for
- // our first user, kLongFlag.
- constexpr static uint32_t kLongFlag = 1 << 16;
- atomic_uint_least32_t serial;
- // we need to keep this buffer around because the property
- // value can be modified whereas name is constant.
- union {
- char value[PROP_VALUE_MAX];
- struct {
- char error_message[kLongLegacyErrorBufferSize];
- uint32_t offset;
- } long_property;
- };
- char name[0];
-
- bool is_long() const {
- return (load_const_atomic(&serial, memory_order_relaxed) & kLongFlag) != 0;
- }
-
- const char* long_value() const {
- // We can't store pointers here since this is shared memory that will have different absolute
- // pointers in different processes. We don't have data_ from prop_area, but since we know
- // `this` is data_ + some offset and long_value is data_ + some other offset, we calculate the
- // offset from `this` to long_value and store it as long_property.offset.
- return reinterpret_cast<const char*>(this) + long_property.offset;
- }
-
- prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen) {
- memcpy(this->name, name, namelen);
- this->name[namelen] = '\0';
- atomic_init(&this->serial, valuelen << 24);
- memcpy(this->value, value, valuelen);
- this->value[valuelen] = '\0';
- }
-
- prop_info(const char* name, uint32_t namelen, uint32_t long_offset) {
- memcpy(this->name, name, namelen);
- this->name[namelen] = '\0';
-
- auto error_value_len = sizeof(kLongLegacyError) - 1;
- atomic_init(&this->serial, error_value_len << 24 | kLongFlag);
- memcpy(this->long_property.error_message, kLongLegacyError, sizeof(kLongLegacyError));
-
- this->long_property.offset = long_offset;
- }
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
-};
-
-static_assert(sizeof(prop_info) == 96, "size of struct prop_info must be 96 bytes");
-
-// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
-__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
-prop_area* __system_property_area__ = nullptr;
-
-static char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
-static size_t pa_data_size;
-static size_t pa_size;
-static bool initialized = false;
-
-static prop_area* map_prop_area_rw(const char* filename, const char* context,
- bool* fsetxattr_failed) {
- /* dev is a tmpfs that we can use to carve a shared workspace
- * out of, so let's do that...
- */
- const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
-
- if (fd < 0) {
- if (errno == EACCES) {
- /* for consistency with the case where the process has already
- * mapped the page in and segfaults when trying to write to it
- */
- abort();
- }
- return nullptr;
- }
-
- if (context) {
- if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc",
- "fsetxattr failed to set context (%s) for \"%s\"", context, filename);
- /*
- * fsetxattr() will fail during system properties tests due to selinux policy.
- * We do not want to create a custom policy for the tester, so we will continue in
- * this function but set a flag that an error has occurred.
- * Init, which is the only daemon that should ever call this function will abort
- * when this error occurs.
- * Otherwise, the tester will ignore it and continue, albeit without any selinux
- * property separation.
- */
- if (fsetxattr_failed) {
- *fsetxattr_failed = true;
- }
- }
- }
-
- if (ftruncate(fd, PA_SIZE) < 0) {
- close(fd);
- return nullptr;
- }
-
- pa_size = PA_SIZE;
- pa_data_size = pa_size - sizeof(prop_area);
-
- void* const memory_area = mmap(nullptr, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (memory_area == MAP_FAILED) {
- close(fd);
- return nullptr;
- }
-
- prop_area* pa = new (memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
-
- close(fd);
- return pa;
-}
-
-static prop_area* map_fd_ro(const int fd) {
- struct stat fd_stat;
- if (fstat(fd, &fd_stat) < 0) {
- return nullptr;
- }
-
- if ((fd_stat.st_uid != 0) || (fd_stat.st_gid != 0) ||
- ((fd_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0) ||
- (fd_stat.st_size < static_cast<off_t>(sizeof(prop_area)))) {
- return nullptr;
- }
-
- pa_size = fd_stat.st_size;
- pa_data_size = pa_size - sizeof(prop_area);
-
- void* const map_result = mmap(nullptr, pa_size, PROT_READ, MAP_SHARED, fd, 0);
- if (map_result == MAP_FAILED) {
- return nullptr;
- }
-
- prop_area* pa = reinterpret_cast<prop_area*>(map_result);
- if ((pa->magic() != PROP_AREA_MAGIC) || (pa->version() != PROP_AREA_VERSION)) {
- munmap(pa, pa_size);
- return nullptr;
- }
-
- return pa;
-}
-
-static prop_area* map_prop_area(const char* filename) {
- int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
- if (fd == -1) return nullptr;
-
- prop_area* map_result = map_fd_ro(fd);
- close(fd);
-
- return map_result;
-}
-
-void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
- const size_t aligned = __BIONIC_ALIGN(size, sizeof(uint_least32_t));
- if (bytes_used_ + aligned > pa_data_size) {
- return nullptr;
- }
-
- *off = bytes_used_;
- bytes_used_ += aligned;
- return data_ + *off;
-}
-
-prop_bt* prop_area::new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off) {
- uint_least32_t new_offset;
- void* const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
- if (p != nullptr) {
- prop_bt* bt = new (p) prop_bt(name, namelen);
- *off = new_offset;
- return bt;
- }
-
- return nullptr;
-}
-
-prop_info* prop_area::new_prop_info(const char* name, uint32_t namelen, const char* value,
- uint32_t valuelen, uint_least32_t* const off) {
- uint_least32_t new_offset;
- void* const p = allocate_obj(sizeof(prop_info) + namelen + 1, &new_offset);
- if (p == nullptr) return nullptr;
-
- prop_info* info;
- if (valuelen >= PROP_VALUE_MAX) {
- uint32_t long_value_offset = 0;
- char* long_location = reinterpret_cast<char*>(allocate_obj(valuelen + 1, &long_value_offset));
- if (!long_location) return nullptr;
-
- memcpy(long_location, value, valuelen);
- long_location[valuelen] = '\0';
-
- // Both new_offset and long_value_offset are offsets based off of data_, however prop_info
- // does not know what data_ is, so we change this offset to be an offset from the prop_info
- // pointer that contains it.
- long_value_offset -= new_offset;
-
- info = new (p) prop_info(name, namelen, long_value_offset);
- } else {
- info = new (p) prop_info(name, namelen, value, valuelen);
- }
- *off = new_offset;
- return info;
-}
-
-void* prop_area::to_prop_obj(uint_least32_t off) {
- if (off > pa_data_size) return nullptr;
-
- return (data_ + off);
-}
-
-inline prop_bt* prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
- uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
- return reinterpret_cast<prop_bt*>(to_prop_obj(off));
-}
-
-inline prop_info* prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
- uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
- return reinterpret_cast<prop_info*>(to_prop_obj(off));
-}
-
-inline prop_bt* prop_area::root_node() {
- return reinterpret_cast<prop_bt*>(to_prop_obj(0));
-}
-
-static int cmp_prop_name(const char* one, uint32_t one_len, const char* two, uint32_t two_len) {
- if (one_len < two_len)
- return -1;
- else if (one_len > two_len)
- return 1;
- else
- return strncmp(one, two, one_len);
-}
-
-prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen,
- bool alloc_if_needed) {
- prop_bt* current = bt;
- while (true) {
- if (!current) {
- return nullptr;
- }
-
- const int ret = cmp_prop_name(name, namelen, current->name, current->namelen);
- if (ret == 0) {
- return current;
- }
-
- if (ret < 0) {
- uint_least32_t left_offset = atomic_load_explicit(¤t->left, memory_order_relaxed);
- if (left_offset != 0) {
- current = to_prop_bt(¤t->left);
- } else {
- if (!alloc_if_needed) {
- return nullptr;
- }
-
- uint_least32_t new_offset;
- prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
- if (new_bt) {
- atomic_store_explicit(¤t->left, new_offset, memory_order_release);
- }
- return new_bt;
- }
- } else {
- uint_least32_t right_offset = atomic_load_explicit(¤t->right, memory_order_relaxed);
- if (right_offset != 0) {
- current = to_prop_bt(¤t->right);
- } else {
- if (!alloc_if_needed) {
- return nullptr;
- }
-
- uint_least32_t new_offset;
- prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
- if (new_bt) {
- atomic_store_explicit(¤t->right, new_offset, memory_order_release);
- }
- return new_bt;
- }
- }
- }
-}
-
-const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen,
- const char* value, uint32_t valuelen,
- bool alloc_if_needed) {
- if (!trie) return nullptr;
-
- const char* remaining_name = name;
- prop_bt* current = trie;
- while (true) {
- const char* sep = strchr(remaining_name, '.');
- const bool want_subtree = (sep != nullptr);
- const uint32_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name);
-
- if (!substr_size) {
- return nullptr;
- }
-
- prop_bt* root = nullptr;
- uint_least32_t children_offset = atomic_load_explicit(¤t->children, memory_order_relaxed);
- if (children_offset != 0) {
- root = to_prop_bt(¤t->children);
- } else if (alloc_if_needed) {
- uint_least32_t new_offset;
- root = new_prop_bt(remaining_name, substr_size, &new_offset);
- if (root) {
- atomic_store_explicit(¤t->children, new_offset, memory_order_release);
- }
- }
-
- if (!root) {
- return nullptr;
- }
-
- current = find_prop_bt(root, remaining_name, substr_size, alloc_if_needed);
- if (!current) {
- return nullptr;
- }
-
- if (!want_subtree) break;
-
- remaining_name = sep + 1;
- }
-
- uint_least32_t prop_offset = atomic_load_explicit(¤t->prop, memory_order_relaxed);
- if (prop_offset != 0) {
- return to_prop_info(¤t->prop);
- } else if (alloc_if_needed) {
- uint_least32_t new_offset;
- prop_info* new_info = new_prop_info(name, namelen, value, valuelen, &new_offset);
- if (new_info) {
- atomic_store_explicit(¤t->prop, new_offset, memory_order_release);
- }
-
- return new_info;
- } else {
- return nullptr;
- }
-}
-
-class PropertyServiceConnection {
- public:
- PropertyServiceConnection() : last_error_(0) {
- socket_ = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (socket_ == -1) {
- last_error_ = errno;
- return;
- }
-
- const size_t namelen = strlen(property_service_socket);
- sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path));
- addr.sun_family = AF_LOCAL;
- socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
-
- if (TEMP_FAILURE_RETRY(connect(socket_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
- last_error_ = errno;
- close(socket_);
- socket_ = -1;
- }
- }
-
- bool IsValid() {
- return socket_ != -1;
- }
-
- int GetLastError() {
- return last_error_;
- }
-
- bool RecvInt32(int32_t* value) {
- int result = TEMP_FAILURE_RETRY(recv(socket_, value, sizeof(*value), MSG_WAITALL));
- return CheckSendRecvResult(result, sizeof(*value));
- }
-
- int socket() {
- return socket_;
- }
-
- ~PropertyServiceConnection() {
- if (socket_ != -1) {
- close(socket_);
- }
- }
-
- private:
- bool CheckSendRecvResult(int result, int expected_len) {
- if (result == -1) {
- last_error_ = errno;
- } else if (result != expected_len) {
- last_error_ = -1;
- } else {
- last_error_ = 0;
- }
-
- return last_error_ == 0;
- }
-
- int socket_;
- int last_error_;
-
- friend class SocketWriter;
-};
-
-class SocketWriter {
- public:
- explicit SocketWriter(PropertyServiceConnection* connection)
- : connection_(connection), iov_index_(0), uint_buf_index_(0)
- {}
-
- SocketWriter& WriteUint32(uint32_t value) {
- CHECK(uint_buf_index_ < kUintBufSize);
- CHECK(iov_index_ < kIovSize);
- uint32_t* ptr = uint_buf_ + uint_buf_index_;
- uint_buf_[uint_buf_index_++] = value;
- iov_[iov_index_].iov_base = ptr;
- iov_[iov_index_].iov_len = sizeof(*ptr);
- ++iov_index_;
- return *this;
- }
-
- SocketWriter& WriteString(const char* value) {
- uint32_t valuelen = strlen(value);
- WriteUint32(valuelen);
- if (valuelen == 0) {
- return *this;
- }
-
- CHECK(iov_index_ < kIovSize);
- iov_[iov_index_].iov_base = const_cast<char*>(value);
- iov_[iov_index_].iov_len = valuelen;
- ++iov_index_;
-
- return *this;
- }
-
- bool Send() {
- if (!connection_->IsValid()) {
- return false;
- }
-
- if (writev(connection_->socket(), iov_, iov_index_) == -1) {
- connection_->last_error_ = errno;
- return false;
- }
-
- iov_index_ = uint_buf_index_ = 0;
- return true;
- }
-
- private:
- static constexpr size_t kUintBufSize = 8;
- static constexpr size_t kIovSize = 8;
-
- PropertyServiceConnection* connection_;
- iovec iov_[kIovSize];
- size_t iov_index_;
- uint32_t uint_buf_[kUintBufSize];
- size_t uint_buf_index_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
-};
-
-struct prop_msg {
- unsigned cmd;
- char name[PROP_NAME_MAX];
- char value[PROP_VALUE_MAX];
-};
-
-static int send_prop_msg(const prop_msg* msg) {
- PropertyServiceConnection connection;
- if (!connection.IsValid()) {
- return connection.GetLastError();
- }
-
- int result = -1;
- int s = connection.socket();
-
- const int num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0));
- if (num_bytes == sizeof(prop_msg)) {
- // We successfully wrote to the property server but now we
- // wait for the property server to finish its work. It
- // acknowledges its completion by closing the socket so we
- // poll here (on nothing), waiting for the socket to close.
- // If you 'adb shell setprop foo bar' you'll see the POLLHUP
- // once the socket closes. Out of paranoia we cap our poll
- // at 250 ms.
- pollfd pollfds[1];
- pollfds[0].fd = s;
- pollfds[0].events = 0;
- const int poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */));
- if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
- result = 0;
- } else {
- // Ignore the timeout and treat it like a success anyway.
- // The init process is single-threaded and its property
- // service is sometimes slow to respond (perhaps it's off
- // starting a child process or something) and thus this
- // times out and the caller thinks it failed, even though
- // it's still getting around to it. So we fake it here,
- // mostly for ctl.* properties, but we do try and wait 250
- // ms so callers who do read-after-write can reliably see
- // what they've written. Most of the time.
- // TODO: fix the system properties design.
- async_safe_format_log(ANDROID_LOG_WARN, "libc",
- "Property service has timed out while trying to set \"%s\" to \"%s\"",
- msg->name, msg->value);
- result = 0;
- }
- }
-
- return result;
-}
-
-bool prop_area::foreach_property(prop_bt* const trie,
- void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
- if (!trie) return false;
-
- uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
- if (left_offset != 0) {
- const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
- if (err < 0) return false;
- }
- uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
- if (prop_offset != 0) {
- prop_info* info = to_prop_info(&trie->prop);
- if (!info) return false;
- propfn(info, cookie);
- }
- uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
- if (children_offset != 0) {
- const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
- if (err < 0) return false;
- }
- uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
- if (right_offset != 0) {
- const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
- if (err < 0) return false;
- }
-
- return true;
-}
-
-const prop_info* prop_area::find(const char* name) {
- return find_property(root_node(), name, strlen(name), nullptr, 0, false);
-}
-
-bool prop_area::add(const char* name, unsigned int namelen, const char* value,
- unsigned int valuelen) {
- return find_property(root_node(), name, namelen, value, valuelen, true);
-}
-
-bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
- return foreach_property(root_node(), propfn, cookie);
-}
-
-class context_node {
- public:
- context_node(context_node* next, const char* context, prop_area* pa)
- : next(next), context_(strdup(context)), pa_(pa), no_access_(false) {
- lock_.init(false);
- }
- ~context_node() {
- unmap();
- free(context_);
- }
- bool open(bool access_rw, bool* fsetxattr_failed);
- bool check_access_and_open();
- void reset_access();
-
- const char* context() const {
- return context_;
- }
- prop_area* pa() {
- return pa_;
- }
-
- context_node* next;
-
- private:
- bool check_access();
- void unmap();
-
- Lock lock_;
- char* context_;
- prop_area* pa_;
- bool no_access_;
-};
-
-struct prefix_node {
- prefix_node(struct prefix_node* next, const char* prefix, context_node* context)
- : prefix(strdup(prefix)), prefix_len(strlen(prefix)), context(context), next(next) {
- }
- ~prefix_node() {
- free(prefix);
- }
- char* prefix;
- const size_t prefix_len;
- context_node* context;
- struct prefix_node* next;
-};
-
-template <typename List, typename... Args>
-static inline void list_add(List** list, Args... args) {
- *list = new List(*list, args...);
-}
-
-static void list_add_after_len(prefix_node** list, const char* prefix, context_node* context) {
- size_t prefix_len = strlen(prefix);
-
- auto next_list = list;
-
- while (*next_list) {
- if ((*next_list)->prefix_len < prefix_len || (*next_list)->prefix[0] == '*') {
- list_add(next_list, prefix, context);
- return;
- }
- next_list = &(*next_list)->next;
- }
- list_add(next_list, prefix, context);
-}
-
-template <typename List, typename Func>
-static void list_foreach(List* list, Func func) {
- while (list) {
- func(list);
- list = list->next;
- }
-}
-
-template <typename List, typename Func>
-static List* list_find(List* list, Func func) {
- while (list) {
- if (func(list)) {
- return list;
- }
- list = list->next;
- }
- return nullptr;
-}
-
-template <typename List>
-static void list_free(List** list) {
- while (*list) {
- auto old_list = *list;
- *list = old_list->next;
- delete old_list;
- }
-}
-
-static prefix_node* prefixes = nullptr;
-static context_node* contexts = nullptr;
-
-/*
- * pthread_mutex_lock() calls into system_properties in the case of contention.
- * This creates a risk of dead lock if any system_properties functions
- * use pthread locks after system_property initialization.
- *
- * For this reason, the below three functions use a bionic Lock and static
- * allocation of memory for each filename.
- */
-
-bool context_node::open(bool access_rw, bool* fsetxattr_failed) {
- lock_.lock();
- if (pa_) {
- lock_.unlock();
- return true;
- }
-
- char filename[PROP_FILENAME_MAX];
- int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename,
- context_);
- if (len < 0 || len > PROP_FILENAME_MAX) {
- lock_.unlock();
- return false;
- }
-
- if (access_rw) {
- pa_ = map_prop_area_rw(filename, context_, fsetxattr_failed);
- } else {
- pa_ = map_prop_area(filename);
- }
- lock_.unlock();
- return pa_;
-}
-
-bool context_node::check_access_and_open() {
- if (!pa_ && !no_access_) {
- if (!check_access() || !open(false, nullptr)) {
- no_access_ = true;
- }
- }
- return pa_;
-}
-
-void context_node::reset_access() {
- if (!check_access()) {
- unmap();
- no_access_ = true;
- } else {
- no_access_ = false;
- }
-}
-
-bool context_node::check_access() {
- char filename[PROP_FILENAME_MAX];
- int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename,
- context_);
- if (len < 0 || len > PROP_FILENAME_MAX) {
- return false;
- }
-
- return access(filename, R_OK) == 0;
-}
-
-void context_node::unmap() {
- if (!pa_) {
- return;
- }
-
- munmap(pa_, pa_size);
- if (pa_ == __system_property_area__) {
- __system_property_area__ = nullptr;
- }
- pa_ = nullptr;
-}
-
-static bool map_system_property_area(bool access_rw, bool* fsetxattr_failed) {
- char filename[PROP_FILENAME_MAX];
- int len =
- async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial",
- property_filename);
- if (len < 0 || len > PROP_FILENAME_MAX) {
- __system_property_area__ = nullptr;
- return false;
- }
-
- if (access_rw) {
- __system_property_area__ =
- map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
- } else {
- __system_property_area__ = map_prop_area(filename);
- }
- return __system_property_area__;
-}
-
-static prop_area* get_prop_area_for_name(const char* name) {
- auto entry = list_find(prefixes, [name](prefix_node* l) {
- return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
- });
- if (!entry) {
- return nullptr;
- }
-
- auto cnode = entry->context;
- if (!cnode->pa()) {
- /*
- * We explicitly do not check no_access_ in this case because unlike the
- * case of foreach(), we want to generate an selinux audit for each
- * non-permitted property access in this function.
- */
- cnode->open(false, nullptr);
- }
- return cnode->pa();
-}
-
-/*
- * The below two functions are duplicated from label_support.c in libselinux.
- * TODO: Find a location suitable for these functions such that both libc and
- * libselinux can share a common source file.
- */
-
-/*
- * The read_spec_entries and read_spec_entry functions may be used to
- * replace sscanf to read entries from spec files. The file and
- * property services now use these.
- */
-
-/* Read an entry from a spec file (e.g. file_contexts) */
-static inline int read_spec_entry(char** entry, char** ptr, int* len) {
- *entry = nullptr;
- char* tmp_buf = nullptr;
-
- while (isspace(**ptr) && **ptr != '\0') (*ptr)++;
-
- tmp_buf = *ptr;
- *len = 0;
-
- while (!isspace(**ptr) && **ptr != '\0') {
- (*ptr)++;
- (*len)++;
- }
-
- if (*len) {
- *entry = strndup(tmp_buf, *len);
- if (!*entry) return -1;
- }
-
- return 0;
-}
-
-/*
- * line_buf - Buffer containing the spec entries .
- * num_args - The number of spec parameter entries to process.
- * ... - A 'char **spec_entry' for each parameter.
- * returns - The number of items processed.
- *
- * This function calls read_spec_entry() to do the actual string processing.
- */
-static int read_spec_entries(char* line_buf, int num_args, ...) {
- char **spec_entry, *buf_p;
- int len, rc, items, entry_len = 0;
- va_list ap;
-
- len = strlen(line_buf);
- if (line_buf[len - 1] == '\n')
- line_buf[len - 1] = '\0';
- else
- /* Handle case if line not \n terminated by bumping
- * the len for the check below (as the line is NUL
- * terminated by getline(3)) */
- len++;
-
- buf_p = line_buf;
- while (isspace(*buf_p)) buf_p++;
-
- /* Skip comment lines and empty lines. */
- if (*buf_p == '#' || *buf_p == '\0') return 0;
-
- /* Process the spec file entries */
- va_start(ap, num_args);
-
- items = 0;
- while (items < num_args) {
- spec_entry = va_arg(ap, char**);
-
- if (len - 1 == buf_p - line_buf) {
- va_end(ap);
- return items;
- }
-
- rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
- if (rc < 0) {
- va_end(ap);
- return rc;
- }
- if (entry_len) items++;
- }
- va_end(ap);
- return items;
-}
-
-static bool initialize_properties_from_file(const char* filename) {
- FILE* file = fopen(filename, "re");
- if (!file) {
- return false;
- }
-
- char* buffer = nullptr;
- size_t line_len;
- char* prop_prefix = nullptr;
- char* context = nullptr;
-
- while (getline(&buffer, &line_len, file) > 0) {
- int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
- if (items <= 0) {
- continue;
- }
- if (items == 1) {
- free(prop_prefix);
- continue;
- }
- /*
- * init uses ctl.* properties as an IPC mechanism and does not write them
- * to a property file, therefore we do not need to create property files
- * to store them.
- */
- if (!strncmp(prop_prefix, "ctl.", 4)) {
- free(prop_prefix);
- free(context);
- continue;
- }
-
- auto old_context =
- list_find(contexts, [context](context_node* l) { return !strcmp(l->context(), context); });
- if (old_context) {
- list_add_after_len(&prefixes, prop_prefix, old_context);
- } else {
- list_add(&contexts, context, nullptr);
- list_add_after_len(&prefixes, prop_prefix, contexts);
- }
- free(prop_prefix);
- free(context);
- }
-
- free(buffer);
- fclose(file);
-
- return true;
-}
-
-static bool initialize_properties() {
- // If we do find /property_contexts, then this is being
- // run as part of the OTA updater on older release that had
- // /property_contexts - b/34370523
- if (initialize_properties_from_file("/property_contexts")) {
- return true;
- }
-
- // Use property_contexts from /system & /vendor, fall back to those from /
- if (access("/system/etc/selinux/plat_property_contexts", R_OK) != -1) {
- if (!initialize_properties_from_file("/system/etc/selinux/plat_property_contexts")) {
- return false;
- }
- // Don't check for failure here, so we always have a sane list of properties.
- // E.g. In case of recovery, the vendor partition will not have mounted and we
- // still need the system / platform properties to function.
- initialize_properties_from_file("/vendor/etc/selinux/nonplat_property_contexts");
- } else {
- if (!initialize_properties_from_file("/plat_property_contexts")) {
- return false;
- }
- initialize_properties_from_file("/nonplat_property_contexts");
- }
-
- return true;
-}
-
-static bool is_dir(const char* pathname) {
- struct stat info;
- if (stat(pathname, &info) == -1) {
- return false;
- }
- return S_ISDIR(info.st_mode);
-}
-
-static void free_and_unmap_contexts() {
- list_free(&prefixes);
- list_free(&contexts);
- if (__system_property_area__) {
- munmap(__system_property_area__, pa_size);
- __system_property_area__ = nullptr;
- }
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_properties_init() {
- // This is called from __libc_init_common, and should leave errno at 0 (http://b/37248982).
- ErrnoRestorer errno_restorer;
-
- if (initialized) {
- list_foreach(contexts, [](context_node* l) { l->reset_access(); });
- return 0;
- }
- if (is_dir(property_filename)) {
- if (!initialize_properties()) {
- return -1;
- }
- if (!map_system_property_area(false, nullptr)) {
- free_and_unmap_contexts();
- return -1;
- }
- } else {
- __system_property_area__ = map_prop_area(property_filename);
- if (!__system_property_area__) {
- return -1;
- }
- list_add(&contexts, "legacy_system_prop_area", __system_property_area__);
- list_add_after_len(&prefixes, "*", contexts);
- }
- initialized = true;
- return 0;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_set_filename(const char* filename) {
- size_t len = strlen(filename);
- if (len >= sizeof(property_filename)) return -1;
-
- strcpy(property_filename, filename);
- return 0;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_area_init() {
- free_and_unmap_contexts();
- mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
- if (!initialize_properties()) {
- return -1;
- }
- bool open_failed = false;
- bool fsetxattr_failed = false;
- list_foreach(contexts, [&fsetxattr_failed, &open_failed](context_node* l) {
- if (!l->open(true, &fsetxattr_failed)) {
- open_failed = true;
- }
- });
- if (open_failed || !map_system_property_area(true, &fsetxattr_failed)) {
- free_and_unmap_contexts();
- return -1;
- }
- initialized = true;
- return fsetxattr_failed ? -2 : 0;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-uint32_t __system_property_area_serial() {
- prop_area* pa = __system_property_area__;
- if (!pa) {
- return -1;
- }
- // Make sure this read fulfilled before __system_property_serial
- return atomic_load_explicit(pa->serial(), memory_order_acquire);
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-const prop_info* __system_property_find(const char* name) {
- if (!__system_property_area__) {
- return nullptr;
- }
-
- prop_area* pa = get_prop_area_for_name(name);
- if (!pa) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
- return nullptr;
- }
-
- return pa->find(name);
-}
-
-static bool is_read_only(const char* name) {
- return strncmp(name, "ro.", 3) == 0;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_read(const prop_info* pi, char* name, char* value) {
- while (true) {
- uint32_t serial = __system_property_serial(pi); // acquire semantics
- size_t len = SERIAL_VALUE_LEN(serial);
- memcpy(value, pi->value, len + 1);
- // TODO: Fix the synchronization scheme here.
- // There is no fully supported way to implement this kind
- // of synchronization in C++11, since the memcpy races with
- // updates to pi, and the data being accessed is not atomic.
- // The following fence is unintuitive, but would be the
- // correct one if memcpy used memory_order_relaxed atomic accesses.
- // In practice it seems unlikely that the generated code would
- // would be any different, so this should be OK.
- atomic_thread_fence(memory_order_acquire);
- if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
- if (name != nullptr) {
- size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX);
- if (namelen >= PROP_NAME_MAX) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc",
- "The property name length for \"%s\" is >= %d;"
- " please use __system_property_read_callback"
- " to read this property. (the name is truncated to \"%s\")",
- pi->name, PROP_NAME_MAX - 1, name);
- }
- }
- if (is_read_only(pi->name) && pi->is_long()) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc",
- "The property \"%s\" has a value with length %zu that is too large for"
- " __system_property_get()/__system_property_read(); use"
- " __system_property_read_callback() instead.",
- pi->name, strlen(pi->long_value()));
- }
- return len;
- }
- }
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-void __system_property_read_callback(const prop_info* pi,
- void (*callback)(void* cookie,
- const char* name,
- const char* value,
- uint32_t serial),
- void* cookie) {
- // Read only properties don't need to copy the value to a temporary buffer, since it can never
- // change.
- if (is_read_only(pi->name)) {
- uint32_t serial = __system_property_serial(pi);
- if (pi->is_long()) {
- callback(cookie, pi->name, pi->long_value(), serial);
- } else {
- callback(cookie, pi->name, pi->value, serial);
- }
- return;
- }
-
- while (true) {
- uint32_t serial = __system_property_serial(pi); // acquire semantics
- size_t len = SERIAL_VALUE_LEN(serial);
- char value_buf[len + 1];
-
- memcpy(value_buf, pi->value, len);
- value_buf[len] = '\0';
-
- // TODO: see todo in __system_property_read function
- atomic_thread_fence(memory_order_acquire);
- if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
- callback(cookie, pi->name, value_buf, serial);
- return;
- }
- }
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_get(const char* name, char* value) {
- const prop_info* pi = __system_property_find(name);
-
- if (pi != 0) {
- return __system_property_read(pi, nullptr, value);
- } else {
- value[0] = 0;
- return 0;
- }
-}
-
-static constexpr uint32_t kProtocolVersion1 = 1;
-static constexpr uint32_t kProtocolVersion2 = 2; // current
-
-static atomic_uint_least32_t g_propservice_protocol_version = 0;
-
-static void detect_protocol_version() {
- char value[PROP_VALUE_MAX];
- if (__system_property_get(kServiceVersionPropertyName, value) == 0) {
- g_propservice_protocol_version = kProtocolVersion1;
- async_safe_format_log(ANDROID_LOG_WARN, "libc",
- "Using old property service protocol (\"%s\" is not set)",
- kServiceVersionPropertyName);
- } else {
- uint32_t version = static_cast<uint32_t>(atoll(value));
- if (version >= kProtocolVersion2) {
- g_propservice_protocol_version = kProtocolVersion2;
- } else {
- async_safe_format_log(ANDROID_LOG_WARN, "libc",
- "Using old property service protocol (\"%s\"=\"%s\")",
- kServiceVersionPropertyName, value);
- g_propservice_protocol_version = kProtocolVersion1;
- }
- }
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_set(const char* key, const char* value) {
- if (key == nullptr) return -1;
- if (value == nullptr) value = "";
-
- if (g_propservice_protocol_version == 0) {
- detect_protocol_version();
- }
-
- if (g_propservice_protocol_version == kProtocolVersion1) {
- // Old protocol does not support long names or values
- if (strlen(key) >= PROP_NAME_MAX) return -1;
- if (strlen(value) >= PROP_VALUE_MAX) return -1;
-
- prop_msg msg;
- memset(&msg, 0, sizeof msg);
- msg.cmd = PROP_MSG_SETPROP;
- strlcpy(msg.name, key, sizeof msg.name);
- strlcpy(msg.value, value, sizeof msg.value);
-
- return send_prop_msg(&msg);
- } else {
- // New protocol only allows long values for ro. properties only.
- if (strlen(value) >= PROP_VALUE_MAX && !is_read_only(key)) return -1;
- // Use proper protocol
- PropertyServiceConnection connection;
- if (!connection.IsValid()) {
- errno = connection.GetLastError();
- async_safe_format_log(ANDROID_LOG_WARN,
- "libc",
- "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)",
- key,
- value,
- errno,
- strerror(errno));
- return -1;
- }
-
- SocketWriter writer(&connection);
- if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
- errno = connection.GetLastError();
- async_safe_format_log(ANDROID_LOG_WARN,
- "libc",
- "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
- key,
- value,
- errno,
- strerror(errno));
- return -1;
- }
-
- int result = -1;
- if (!connection.RecvInt32(&result)) {
- errno = connection.GetLastError();
- async_safe_format_log(ANDROID_LOG_WARN,
- "libc",
- "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
- key,
- value,
- errno,
- strerror(errno));
- return -1;
- }
-
- 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);
- return -1;
- }
-
- return 0;
- }
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_update(prop_info* pi, const char* value, unsigned int len) {
- if (len >= PROP_VALUE_MAX) {
- return -1;
- }
-
- prop_area* pa = __system_property_area__;
-
- if (!pa) {
- return -1;
- }
-
- uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
- serial |= 1;
- atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
- // The memcpy call here also races. Again pretend it
- // used memory_order_relaxed atomics, and use the analogous
- // counterintuitive fence.
- atomic_thread_fence(memory_order_release);
- strlcpy(pi->value, value, len + 1);
-
- atomic_store_explicit(&pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release);
- __futex_wake(&pi->serial, INT32_MAX);
-
- atomic_store_explicit(pa->serial(), atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
- memory_order_release);
- __futex_wake(pa->serial(), INT32_MAX);
-
- return 0;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_add(const char* name, unsigned int namelen, const char* value,
- unsigned int valuelen) {
- if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) {
- return -1;
- }
-
- if (namelen < 1) {
- return -1;
- }
-
- if (!__system_property_area__) {
- return -1;
- }
-
- prop_area* pa = get_prop_area_for_name(name);
-
- if (!pa) {
- async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
- return -1;
- }
-
- bool ret = pa->add(name, namelen, value, valuelen);
- if (!ret) {
- return -1;
- }
-
- // There is only a single mutator, but we want to make sure that
- // updates are visible to a reader waiting for the update.
- atomic_store_explicit(
- __system_property_area__->serial(),
- atomic_load_explicit(__system_property_area__->serial(), memory_order_relaxed) + 1,
- memory_order_release);
- __futex_wake(__system_property_area__->serial(), INT32_MAX);
- return 0;
-}
-
-// Wait for non-locked serial, and retrieve it with acquire semantics.
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-uint32_t __system_property_serial(const prop_info* pi) {
- uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
- while (SERIAL_DIRTY(serial)) {
- __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), serial, nullptr);
- serial = load_const_atomic(&pi->serial, memory_order_acquire);
- }
- return serial;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-uint32_t __system_property_wait_any(uint32_t old_serial) {
- uint32_t new_serial;
- __system_property_wait(nullptr, old_serial, &new_serial, nullptr);
- return new_serial;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-bool __system_property_wait(const prop_info* pi,
- uint32_t old_serial,
- uint32_t* new_serial_ptr,
- const timespec* relative_timeout) {
- // Are we waiting on the global serial or a specific serial?
- atomic_uint_least32_t* serial_ptr;
- if (pi == nullptr) {
- if (__system_property_area__ == nullptr) return -1;
- serial_ptr = __system_property_area__->serial();
- } else {
- serial_ptr = const_cast<atomic_uint_least32_t*>(&pi->serial);
- }
-
- uint32_t new_serial;
- do {
- int rc;
- if ((rc = __futex_wait(serial_ptr, old_serial, relative_timeout)) != 0 && rc == -ETIMEDOUT) {
- return false;
- }
- new_serial = load_const_atomic(serial_ptr, memory_order_acquire);
- } while (new_serial == old_serial);
-
- *new_serial_ptr = new_serial;
- return true;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-const prop_info* __system_property_find_nth(unsigned n) {
- struct find_nth {
- const uint32_t sought;
- uint32_t current;
- const prop_info* result;
-
- explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {}
- static void fn(const prop_info* pi, void* ptr) {
- find_nth* self = reinterpret_cast<find_nth*>(ptr);
- if (self->current++ == self->sought) self->result = pi;
- }
- } state(n);
- __system_property_foreach(find_nth::fn, &state);
- return state.result;
-}
-
-__BIONIC_WEAK_FOR_NATIVE_BRIDGE
-int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
- if (!__system_property_area__) {
- return -1;
- }
-
- list_foreach(contexts, [propfn, cookie](context_node* l) {
- if (l->check_access_and_open()) {
- l->pa()->foreach(propfn, cookie);
- }
- });
- return 0;
-}
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index fff80f6..68144cd 100644
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -27,7 +27,7 @@
# Set up LD_LIBRARY_PATH to include libclang.so, libLLVM.so, and etc.
# Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help.
-clang.cindex.Config.set_library_path(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64'))
+clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64/libclang_android.so'))
from defaults import kCppUndefinedMacro
from defaults import kernel_remove_config_macros
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index b0fb95f..1afdc77 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -58,8 +58,6 @@
# Replace tokens in the output according to this mapping.
kernel_token_replacements = {
- # The kernel's ARG_MAX is actually the "minimum" maximum (see fs/exec.c).
- "ARG_MAX": "_KERNEL_ARG_MAX",
# The kernel usage of __unused for unused struct fields conflicts with the macro defined in <sys/cdefs.h>.
"__unused": "__linux_unused",
# The kernel usage of C++ keywords causes problems for C++ code so rename.
@@ -84,8 +82,6 @@
"epoll_event": "__kernel_uapi_epoll_event",
# This causes problems when trying to export the headers for the ndk.
"__attribute_const__": "__attribute__((__const__))",
- # There is a mismatch between upstream and our kernels for this structure.
- "binder_fd_array_object": "__kernel_binder_fd_array_object",
}
# This is the set of known static inline functions that we want to keep
diff --git a/libc/kernel/uapi/asm-arm/asm/kvm.h b/libc/kernel/uapi/asm-arm/asm/kvm.h
index c814a09..2332ae2 100644
--- a/libc/kernel/uapi/asm-arm/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm/asm/kvm.h
@@ -147,6 +147,12 @@
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
#define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff
#define VGIC_LEVEL_INFO_LINE_LEVEL 0
+#define KVM_ARM_VCPU_PMU_V3_CTRL 0
+#define KVM_ARM_VCPU_PMU_V3_IRQ 0
+#define KVM_ARM_VCPU_PMU_V3_INIT 1
+#define KVM_ARM_VCPU_TIMER_CTRL 1
+#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
+#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
diff --git a/libc/kernel/uapi/asm-arm64/asm/hwcap.h b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
index 4ab16ad..60b8305 100644
--- a/libc/kernel/uapi/asm-arm64/asm/hwcap.h
+++ b/libc/kernel/uapi/asm-arm64/asm/hwcap.h
@@ -34,4 +34,5 @@
#define HWCAP_JSCVT (1 << 13)
#define HWCAP_FCMA (1 << 14)
#define HWCAP_LRCPC (1 << 15)
+#define HWCAP_DCPOP (1 << 16)
#endif
diff --git a/libc/kernel/uapi/asm-arm64/asm/kvm.h b/libc/kernel/uapi/asm-arm64/asm/kvm.h
index dade888..a68a8a2 100644
--- a/libc/kernel/uapi/asm-arm64/asm/kvm.h
+++ b/libc/kernel/uapi/asm-arm64/asm/kvm.h
@@ -147,6 +147,9 @@
#define KVM_ARM_VCPU_PMU_V3_CTRL 0
#define KVM_ARM_VCPU_PMU_V3_IRQ 0
#define KVM_ARM_VCPU_PMU_V3_INIT 1
+#define KVM_ARM_VCPU_TIMER_CTRL 1
+#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0
+#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1
#define KVM_ARM_IRQ_TYPE_SHIFT 24
#define KVM_ARM_IRQ_TYPE_MASK 0xff
#define KVM_ARM_IRQ_VCPU_SHIFT 16
diff --git a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
index 80d61b0..be2464e 100644
--- a/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
+++ b/libc/kernel/uapi/asm-arm64/asm/sigcontext.h
@@ -43,4 +43,11 @@
struct _aarch64_ctx head;
__u64 esr;
};
+#define EXTRA_MAGIC 0x45585401
+struct extra_context {
+ struct _aarch64_ctx head;
+ __u64 datap;
+ __u32 size;
+ __u32 __reserved[3];
+};
#endif
diff --git a/libc/kernel/uapi/asm-generic/hugetlb_encode.h b/libc/kernel/uapi/asm-generic/hugetlb_encode.h
new file mode 100644
index 0000000..68849b3
--- /dev/null
+++ b/libc/kernel/uapi/asm-generic/hugetlb_encode.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_
+#define _ASM_GENERIC_HUGETLB_ENCODE_H_
+#define HUGETLB_FLAG_ENCODE_SHIFT 26
+#define HUGETLB_FLAG_ENCODE_MASK 0x3f
+#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT)
+#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT)
+#endif
diff --git a/libc/kernel/uapi/asm-generic/ioctls.h b/libc/kernel/uapi/asm-generic/ioctls.h
index 792bf0f..41dbce2 100644
--- a/libc/kernel/uapi/asm-generic/ioctls.h
+++ b/libc/kernel/uapi/asm-generic/ioctls.h
@@ -80,6 +80,7 @@
#define TIOCGPKT _IOR('T', 0x38, int)
#define TIOCGPTLCK _IOR('T', 0x39, int)
#define TIOCGEXCL _IOR('T', 0x40, int)
+#define TIOCGPTPEER _IO('T', 0x41)
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
diff --git a/libc/kernel/uapi/asm-generic/mman-common.h b/libc/kernel/uapi/asm-generic/mman-common.h
index 047743d..a15624a 100644
--- a/libc/kernel/uapi/asm-generic/mman-common.h
+++ b/libc/kernel/uapi/asm-generic/mman-common.h
@@ -52,9 +52,9 @@
#define MADV_NOHUGEPAGE 15
#define MADV_DONTDUMP 16
#define MADV_DODUMP 17
+#define MADV_WIPEONFORK 18
+#define MADV_KEEPONFORK 19
#define MAP_FILE 0
-#define MAP_HUGE_SHIFT 26
-#define MAP_HUGE_MASK 0x3f
#define PKEY_DISABLE_ACCESS 0x1
#define PKEY_DISABLE_WRITE 0x2
#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)
diff --git a/libc/kernel/uapi/asm-generic/siginfo.h b/libc/kernel/uapi/asm-generic/siginfo.h
index f98fd73..669c9d4 100644
--- a/libc/kernel/uapi/asm-generic/siginfo.h
+++ b/libc/kernel/uapi/asm-generic/siginfo.h
@@ -126,75 +126,66 @@
#define si_syscall _sifields._sigsys._syscall
#define si_arch _sifields._sigsys._arch
#endif
-#define __SI_KILL 0
-#define __SI_TIMER 0
-#define __SI_POLL 0
-#define __SI_FAULT 0
-#define __SI_CHLD 0
-#define __SI_RT 0
-#define __SI_MESGQ 0
-#define __SI_SYS 0
-#define __SI_CODE(T,N) (N)
#define SI_USER 0
#define SI_KERNEL 0x80
#define SI_QUEUE - 1
-#define SI_TIMER __SI_CODE(__SI_TIMER, - 2)
-#define SI_MESGQ __SI_CODE(__SI_MESGQ, - 3)
+#define SI_TIMER - 2
+#define SI_MESGQ - 3
#define SI_ASYNCIO - 4
#define SI_SIGIO - 5
#define SI_TKILL - 6
#define SI_DETHREAD - 7
#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
-#define ILL_ILLOPC (__SI_FAULT | 1)
-#define ILL_ILLOPN (__SI_FAULT | 2)
-#define ILL_ILLADR (__SI_FAULT | 3)
-#define ILL_ILLTRP (__SI_FAULT | 4)
-#define ILL_PRVOPC (__SI_FAULT | 5)
-#define ILL_PRVREG (__SI_FAULT | 6)
-#define ILL_COPROC (__SI_FAULT | 7)
-#define ILL_BADSTK (__SI_FAULT | 8)
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
#define NSIGILL 8
-#define FPE_INTDIV (__SI_FAULT | 1)
-#define FPE_INTOVF (__SI_FAULT | 2)
-#define FPE_FLTDIV (__SI_FAULT | 3)
-#define FPE_FLTOVF (__SI_FAULT | 4)
-#define FPE_FLTUND (__SI_FAULT | 5)
-#define FPE_FLTRES (__SI_FAULT | 6)
-#define FPE_FLTINV (__SI_FAULT | 7)
-#define FPE_FLTSUB (__SI_FAULT | 8)
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
#define NSIGFPE 8
-#define SEGV_MAPERR (__SI_FAULT | 1)
-#define SEGV_ACCERR (__SI_FAULT | 2)
-#define SEGV_BNDERR (__SI_FAULT | 3)
-#define SEGV_PKUERR (__SI_FAULT | 4)
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+#define SEGV_PKUERR 4
#define NSIGSEGV 4
-#define BUS_ADRALN (__SI_FAULT | 1)
-#define BUS_ADRERR (__SI_FAULT | 2)
-#define BUS_OBJERR (__SI_FAULT | 3)
-#define BUS_MCEERR_AR (__SI_FAULT | 4)
-#define BUS_MCEERR_AO (__SI_FAULT | 5)
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
#define NSIGBUS 5
-#define TRAP_BRKPT (__SI_FAULT | 1)
-#define TRAP_TRACE (__SI_FAULT | 2)
-#define TRAP_BRANCH (__SI_FAULT | 3)
-#define TRAP_HWBKPT (__SI_FAULT | 4)
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define TRAP_BRANCH 3
+#define TRAP_HWBKPT 4
#define NSIGTRAP 4
-#define CLD_EXITED (__SI_CHLD | 1)
-#define CLD_KILLED (__SI_CHLD | 2)
-#define CLD_DUMPED (__SI_CHLD | 3)
-#define CLD_TRAPPED (__SI_CHLD | 4)
-#define CLD_STOPPED (__SI_CHLD | 5)
-#define CLD_CONTINUED (__SI_CHLD | 6)
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
#define NSIGCHLD 6
-#define POLL_IN (__SI_POLL | 1)
-#define POLL_OUT (__SI_POLL | 2)
-#define POLL_MSG (__SI_POLL | 3)
-#define POLL_ERR (__SI_POLL | 4)
-#define POLL_PRI (__SI_POLL | 5)
-#define POLL_HUP (__SI_POLL | 6)
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
#define NSIGPOLL 6
-#define SYS_SECCOMP (__SI_SYS | 1)
+#define SYS_SECCOMP 1
#define NSIGSYS 1
#define SIGEV_SIGNAL 0
#define SIGEV_NONE 1
diff --git a/libc/kernel/uapi/asm-generic/socket.h b/libc/kernel/uapi/asm-generic/socket.h
index d1dc0099..b821554 100644
--- a/libc/kernel/uapi/asm-generic/socket.h
+++ b/libc/kernel/uapi/asm-generic/socket.h
@@ -85,4 +85,7 @@
#define SO_MEMINFO 55
#define SO_INCOMING_NAPI_ID 56
#define SO_COOKIE 57
+#define SCM_TIMESTAMPING_PKTINFO 58
+#define SO_PEERGROUPS 59
+#define SO_ZEROCOPY 60
#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/inst.h b/libc/kernel/uapi/asm-mips/asm/inst.h
index 46a65e6..61fa3d6 100644
--- a/libc/kernel/uapi/asm-mips/asm/inst.h
+++ b/libc/kernel/uapi/asm-mips/asm/inst.h
@@ -414,10 +414,13 @@
};
enum bshfl_func {
wsbh_op = 0x2,
- dshd_op = 0x5,
seb_op = 0x10,
seh_op = 0x18,
};
+enum dbshfl_func {
+ dsbh_op = 0x2,
+ dshd_op = 0x5,
+};
enum msa_func {
msa_elm_op = 0x19,
};
@@ -798,6 +801,10 @@
__BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(signed int s10 : 10, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int wd : 5, __BITFIELD_FIELD(unsigned int func : 4, __BITFIELD_FIELD(unsigned int df : 2,;
))))))
};
+struct dsp_format {
+ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int base : 5, __BITFIELD_FIELD(unsigned int index : 5, __BITFIELD_FIELD(unsigned int rd : 5, __BITFIELD_FIELD(unsigned int op : 5, __BITFIELD_FIELD(unsigned int func : 6,;
+ ))))))
+};
struct spec3_format {
__BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rs : 5, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 9, __BITFIELD_FIELD(unsigned int func : 7,;
)))))
@@ -883,7 +890,7 @@
))))
};
struct mm16_r5_format {
- __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(signed int simmediate : 5, __BITFIELD_FIELD(unsigned int : 16,;
+ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16,;
))))
};
struct m16e_rr {
@@ -933,6 +940,7 @@
struct b_format b_format;
struct ps_format ps_format;
struct v_format v_format;
+ struct dsp_format dsp_format;
struct spec3_format spec3_format;
struct fb_format fb_format;
struct fp0_format fp0_format;
diff --git a/libc/kernel/uapi/asm-mips/asm/ioctls.h b/libc/kernel/uapi/asm-mips/asm/ioctls.h
index 1845c65..a4a40b0 100644
--- a/libc/kernel/uapi/asm-mips/asm/ioctls.h
+++ b/libc/kernel/uapi/asm-mips/asm/ioctls.h
@@ -84,6 +84,7 @@
#define TIOCGPKT _IOR('T', 0x38, int)
#define TIOCGPTLCK _IOR('T', 0x39, int)
#define TIOCGEXCL _IOR('T', 0x40, int)
+#define TIOCGPTPEER _IO('T', 0x41)
#define TIOCSCTTY 0x5480
#define TIOCGSOFTCAR 0x5481
#define TIOCSSOFTCAR 0x5482
diff --git a/libc/kernel/uapi/asm-mips/asm/mman.h b/libc/kernel/uapi/asm-mips/asm/mman.h
index ad08f7a..b976885 100644
--- a/libc/kernel/uapi/asm-mips/asm/mman.h
+++ b/libc/kernel/uapi/asm-mips/asm/mman.h
@@ -66,9 +66,9 @@
#define MADV_NOHUGEPAGE 15
#define MADV_DONTDUMP 16
#define MADV_DODUMP 17
+#define MADV_WIPEONFORK 18
+#define MADV_KEEPONFORK 19
#define MAP_FILE 0
-#define MAP_HUGE_SHIFT 26
-#define MAP_HUGE_MASK 0x3f
#define PKEY_DISABLE_ACCESS 0x1
#define PKEY_DISABLE_WRITE 0x2
#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)
diff --git a/libc/kernel/uapi/asm-mips/asm/siginfo.h b/libc/kernel/uapi/asm-mips/asm/siginfo.h
index b652925..413abd9 100644
--- a/libc/kernel/uapi/asm-mips/asm/siginfo.h
+++ b/libc/kernel/uapi/asm-mips/asm/siginfo.h
@@ -95,6 +95,6 @@
#undef SI_TIMER
#undef SI_MESGQ
#define SI_ASYNCIO - 2
-#define SI_TIMER __SI_CODE(__SI_TIMER, - 3)
-#define SI_MESGQ __SI_CODE(__SI_MESGQ, - 4)
+#define SI_TIMER - 3
+#define SI_MESGQ - 4
#endif
diff --git a/libc/kernel/uapi/asm-mips/asm/socket.h b/libc/kernel/uapi/asm-mips/asm/socket.h
index e97ae58..b8de15c 100644
--- a/libc/kernel/uapi/asm-mips/asm/socket.h
+++ b/libc/kernel/uapi/asm-mips/asm/socket.h
@@ -84,4 +84,7 @@
#define SO_MEMINFO 55
#define SO_INCOMING_NAPI_ID 56
#define SO_COOKIE 57
+#define SCM_TIMESTAMPING_PKTINFO 58
+#define SO_PEERGROUPS 59
+#define SO_ZEROCOPY 60
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/hyperv.h b/libc/kernel/uapi/asm-x86/asm/hyperv.h
index 2d4b97a..d5c9b19 100644
--- a/libc/kernel/uapi/asm-x86/asm/hyperv.h
+++ b/libc/kernel/uapi/asm-x86/asm/hyperv.h
@@ -32,8 +32,7 @@
#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE (1 << 1)
#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
#define HV_X64_MSR_REFERENCE_TSC 0x40000021
-#define HV_X64_MSR_APIC_FREQUENCY_AVAILABLE (1 << 11)
-#define HV_X64_MSR_TSC_FREQUENCY_AVAILABLE (1 << 11)
+#define HV_X64_ACCESS_FREQUENCY_MSRS (1 << 11)
#define HV_X64_MSR_SYNIC_AVAILABLE (1 << 2)
#define HV_X64_MSR_SYNTIMER_AVAILABLE (1 << 3)
#define HV_X64_MSR_APIC_ACCESS_AVAILABLE (1 << 4)
@@ -41,6 +40,7 @@
#define HV_X64_MSR_VP_INDEX_AVAILABLE (1 << 6)
#define HV_X64_MSR_RESET_AVAILABLE (1 << 7)
#define HV_X64_MSR_STAT_PAGES_AVAILABLE (1 << 8)
+#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE (1 << 8)
#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
#define HV_X64_CREATE_PARTITIONS (1 << 0)
#define HV_X64_ACCESS_PARTITION_ID (1 << 1)
@@ -68,6 +68,7 @@
#define HV_X64_SYSTEM_RESET_RECOMMENDED (1 << 4)
#define HV_X64_RELAXED_TIMING_RECOMMENDED (1 << 5)
#define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9)
+#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11)
#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
#define HV_X64_MSR_HYPERCALL 0x40000001
@@ -121,7 +122,11 @@
#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003
#define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
+#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
#define HVCALL_POST_MESSAGE 0x005c
#define HVCALL_SIGNAL_EVENT 0x005d
#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE 0x00000001
@@ -133,6 +138,14 @@
#define HV_PROCESSOR_POWER_STATE_C1 1
#define HV_PROCESSOR_POWER_STATE_C2 2
#define HV_PROCESSOR_POWER_STATE_C3 3
+#define HV_FLUSH_ALL_PROCESSORS BIT(0)
+#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1)
+#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2)
+#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
+enum HV_GENERIC_SET_FORMAT {
+ HV_GENERIC_SET_SPARCE_4K,
+ HV_GENERIC_SET_ALL,
+};
#define HV_STATUS_SUCCESS 0
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
diff --git a/libc/kernel/uapi/asm-x86/asm/kvm_para.h b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
index 78008df..b7635cb 100644
--- a/libc/kernel/uapi/asm-x86/asm/kvm_para.h
+++ b/libc/kernel/uapi/asm-x86/asm/kvm_para.h
@@ -61,6 +61,7 @@
#define KVM_MAX_MMU_OP_BATCH 32
#define KVM_ASYNC_PF_ENABLED (1 << 0)
#define KVM_ASYNC_PF_SEND_ALWAYS (1 << 1)
+#define KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT (1 << 2)
#define KVM_MMU_OP_WRITE_PTE 1
#define KVM_MMU_OP_FLUSH_TLB 2
#define KVM_MMU_OP_RELEASE_PT 3
diff --git a/libc/kernel/uapi/asm-x86/asm/mman.h b/libc/kernel/uapi/asm-x86/asm/mman.h
index b958829..1061a6f 100644
--- a/libc/kernel/uapi/asm-x86/asm/mman.h
+++ b/libc/kernel/uapi/asm-x86/asm/mman.h
@@ -19,7 +19,5 @@
#ifndef _ASM_X86_MMAN_H
#define _ASM_X86_MMAN_H
#define MAP_32BIT 0x40
-#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
-#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
#include <asm-generic/mman.h>
#endif
diff --git a/libc/kernel/uapi/asm-x86/asm/processor-flags.h b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
index 9f61c0a..f0f8dd2 100644
--- a/libc/kernel/uapi/asm-x86/asm/processor-flags.h
+++ b/libc/kernel/uapi/asm-x86/asm/processor-flags.h
@@ -104,6 +104,8 @@
#define X86_CR4_OSFXSR _BITUL(X86_CR4_OSFXSR_BIT)
#define X86_CR4_OSXMMEXCPT_BIT 10
#define X86_CR4_OSXMMEXCPT _BITUL(X86_CR4_OSXMMEXCPT_BIT)
+#define X86_CR4_LA57_BIT 12
+#define X86_CR4_LA57 _BITUL(X86_CR4_LA57_BIT)
#define X86_CR4_VMXE_BIT 13
#define X86_CR4_VMXE _BITUL(X86_CR4_VMXE_BIT)
#define X86_CR4_SMXE_BIT 14
diff --git a/libc/kernel/uapi/drm/amdgpu_drm.h b/libc/kernel/uapi/drm/amdgpu_drm.h
index f5e8b16..6ae9c9c 100644
--- a/libc/kernel/uapi/drm/amdgpu_drm.h
+++ b/libc/kernel/uapi/drm/amdgpu_drm.h
@@ -34,6 +34,7 @@
#define DRM_AMDGPU_GEM_OP 0x10
#define DRM_AMDGPU_GEM_USERPTR 0x11
#define DRM_AMDGPU_WAIT_FENCES 0x12
+#define DRM_AMDGPU_VM 0x13
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
#define DRM_IOCTL_AMDGPU_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_CTX, union drm_amdgpu_ctx)
@@ -47,6 +48,7 @@
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
+#define DRM_IOCTL_AMDGPU_VM DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_VM, union drm_amdgpu_vm)
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
#define AMDGPU_GEM_DOMAIN_VRAM 0x4
@@ -123,6 +125,19 @@
struct drm_amdgpu_ctx_in in;
union drm_amdgpu_ctx_out out;
};
+#define AMDGPU_VM_OP_RESERVE_VMID 1
+#define AMDGPU_VM_OP_UNRESERVE_VMID 2
+struct drm_amdgpu_vm_in {
+ __u32 op;
+ __u32 flags;
+};
+struct drm_amdgpu_vm_out {
+ __u64 flags;
+};
+union drm_amdgpu_vm {
+ struct drm_amdgpu_vm_in in;
+ struct drm_amdgpu_vm_out out;
+};
#define AMDGPU_GEM_USERPTR_READONLY (1 << 0)
#define AMDGPU_GEM_USERPTR_ANONONLY (1 << 1)
#define AMDGPU_GEM_USERPTR_VALIDATE (1 << 2)
@@ -262,11 +277,15 @@
#define AMDGPU_HW_IP_UVD 3
#define AMDGPU_HW_IP_VCE 4
#define AMDGPU_HW_IP_UVD_ENC 5
-#define AMDGPU_HW_IP_NUM 6
+#define AMDGPU_HW_IP_VCN_DEC 6
+#define AMDGPU_HW_IP_VCN_ENC 7
+#define AMDGPU_HW_IP_NUM 8
#define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1
#define AMDGPU_CHUNK_ID_IB 0x01
#define AMDGPU_CHUNK_ID_FENCE 0x02
#define AMDGPU_CHUNK_ID_DEPENDENCIES 0x03
+#define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04
+#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
struct drm_amdgpu_cs_chunk {
__u32 chunk_id;
__u32 length_dw;
@@ -309,6 +328,9 @@
__u32 handle;
__u32 offset;
};
+struct drm_amdgpu_cs_chunk_sem {
+ __u32 handle;
+};
struct drm_amdgpu_cs_chunk_data {
union {
struct drm_amdgpu_cs_chunk_ib ib_data;
@@ -358,6 +380,7 @@
#define AMDGPU_INFO_SENSOR_GPU_AVG_POWER 0x5
#define AMDGPU_INFO_SENSOR_VDDNB 0x6
#define AMDGPU_INFO_SENSOR_VDDGFX 0x7
+#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E
#define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0
#define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff
#define AMDGPU_INFO_MMR_SH_INDEX_SHIFT 8
@@ -480,6 +503,7 @@
__u32 gs_prim_buffer_depth;
__u32 max_gs_waves_per_vgt;
__u32 _pad1;
+ __u32 cu_ao_bitmap[4][4];
};
struct drm_amdgpu_info_hw_ip {
__u32 hw_ip_version_major;
@@ -513,6 +537,7 @@
#define AMDGPU_FAMILY_VI 130
#define AMDGPU_FAMILY_CZ 135
#define AMDGPU_FAMILY_AI 141
+#define AMDGPU_FAMILY_RV 142
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/armada_drm.h b/libc/kernel/uapi/drm/armada_drm.h
index 331a558..ea1f37d 100644
--- a/libc/kernel/uapi/drm/armada_drm.h
+++ b/libc/kernel/uapi/drm/armada_drm.h
@@ -26,23 +26,23 @@
#define DRM_ARMADA_GEM_PWRITE 0x03
#define ARMADA_IOCTL(dir,name,str) DRM_ ##dir(DRM_COMMAND_BASE + DRM_ARMADA_ ##name, struct drm_armada_ ##str)
struct drm_armada_gem_create {
- uint32_t handle;
- uint32_t size;
+ __u32 handle;
+ __u32 size;
};
#define DRM_IOCTL_ARMADA_GEM_CREATE ARMADA_IOCTL(IOWR, GEM_CREATE, gem_create)
struct drm_armada_gem_mmap {
- uint32_t handle;
- uint32_t pad;
- uint64_t offset;
- uint64_t size;
- uint64_t addr;
+ __u32 handle;
+ __u32 pad;
+ __u64 offset;
+ __u64 size;
+ __u64 addr;
};
#define DRM_IOCTL_ARMADA_GEM_MMAP ARMADA_IOCTL(IOWR, GEM_MMAP, gem_mmap)
struct drm_armada_gem_pwrite {
- uint64_t ptr;
- uint32_t handle;
- uint32_t offset;
- uint32_t size;
+ __u64 ptr;
+ __u32 handle;
+ __u32 offset;
+ __u32 size;
};
#define DRM_IOCTL_ARMADA_GEM_PWRITE ARMADA_IOCTL(IOW, GEM_PWRITE, gem_pwrite)
#ifdef __cplusplus
diff --git a/libc/kernel/uapi/drm/drm.h b/libc/kernel/uapi/drm/drm.h
index 251deeb..6863dc1 100644
--- a/libc/kernel/uapi/drm/drm.h
+++ b/libc/kernel/uapi/drm/drm.h
@@ -361,6 +361,7 @@
#define DRM_CAP_ADDFB2_MODIFIERS 0x10
#define DRM_CAP_PAGE_FLIP_TARGET 0x11
#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12
+#define DRM_CAP_SYNCOBJ 0x13
struct drm_get_cap {
__u64 capability;
__u64 value;
@@ -379,6 +380,38 @@
__u32 flags;
__s32 fd;
};
+struct drm_syncobj_create {
+ __u32 handle;
+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0)
+ __u32 flags;
+};
+struct drm_syncobj_destroy {
+ __u32 handle;
+ __u32 pad;
+};
+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0)
+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0)
+struct drm_syncobj_handle {
+ __u32 handle;
+ __u32 flags;
+ __s32 fd;
+ __u32 pad;
+};
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0)
+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1)
+struct drm_syncobj_wait {
+ __u64 handles;
+ __s64 timeout_nsec;
+ __u32 count_handles;
+ __u32 flags;
+ __u32 first_signaled;
+ __u32 pad;
+};
+struct drm_syncobj_array {
+ __u64 handles;
+ __u32 count_handles;
+ __u32 pad;
+};
#ifdef __cplusplus
#endif
#include "drm_mode.h"
@@ -477,6 +510,13 @@
#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle)
+#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait)
+#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array)
+#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array)
#define DRM_COMMAND_BASE 0x40
#define DRM_COMMAND_END 0xA0
struct drm_event {
diff --git a/libc/kernel/uapi/drm/drm_fourcc.h b/libc/kernel/uapi/drm/drm_fourcc.h
index 630ad30..da416cf 100644
--- a/libc/kernel/uapi/drm/drm_fourcc.h
+++ b/libc/kernel/uapi/drm/drm_fourcc.h
@@ -105,11 +105,16 @@
#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04
#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05
#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06
+#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
#define fourcc_mod_code(vendor,val) ((((__u64) DRM_FORMAT_MOD_VENDOR_ ##vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1)
#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2)
#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3)
+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4)
+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1)
#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2)
@@ -121,6 +126,7 @@
#define fourcc_mod_tegra_param(m) (m & ((1ULL << __fourcc_mod_tegra_mode_shift) - 1))
#define NV_FORMAT_MOD_TEGRA_TILED fourcc_mod_tegra_code(1, 0)
#define NV_FORMAT_MOD_TEGRA_16BX2_BLOCK(v) fourcc_mod_tegra_code(2, v)
+#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1)
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/drm_mode.h b/libc/kernel/uapi/drm/drm_mode.h
index 9e7ee92..5e97a72 100644
--- a/libc/kernel/uapi/drm/drm_mode.h
+++ b/libc/kernel/uapi/drm/drm_mode.h
@@ -79,6 +79,14 @@
#define DRM_MODE_DIRTY_ANNOTATE 2
#define DRM_MODE_LINK_STATUS_GOOD 0
#define DRM_MODE_LINK_STATUS_BAD 1
+#define DRM_MODE_ROTATE_0 (1 << 0)
+#define DRM_MODE_ROTATE_90 (1 << 1)
+#define DRM_MODE_ROTATE_180 (1 << 2)
+#define DRM_MODE_ROTATE_270 (1 << 3)
+#define DRM_MODE_ROTATE_MASK (DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270)
+#define DRM_MODE_REFLECT_X (1 << 4)
+#define DRM_MODE_REFLECT_Y (1 << 5)
+#define DRM_MODE_REFLECT_MASK (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y)
struct drm_mode_modeinfo {
__u32 clock;
__u16 hdisplay;
@@ -396,6 +404,21 @@
__u64 reserved;
__u64 user_data;
};
+struct drm_format_modifier_blob {
+#define FORMAT_BLOB_CURRENT 1
+ __u32 version;
+ __u32 flags;
+ __u32 count_formats;
+ __u32 formats_offset;
+ __u32 count_modifiers;
+ __u32 modifiers_offset;
+};
+struct drm_format_modifier {
+ __u64 formats;
+ __u32 offset;
+ __u32 pad;
+ __u64 modifier;
+};
struct drm_mode_create_blob {
__u64 data;
__u32 length;
diff --git a/libc/kernel/uapi/drm/i915_drm.h b/libc/kernel/uapi/drm/i915_drm.h
index af6f064..50ea43a 100644
--- a/libc/kernel/uapi/drm/i915_drm.h
+++ b/libc/kernel/uapi/drm/i915_drm.h
@@ -172,6 +172,8 @@
#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34
#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35
#define DRM_I915_PERF_OPEN 0x36
+#define DRM_I915_PERF_ADD_CONFIG 0x37
+#define DRM_I915_PERF_REMOVE_CONFIG 0x38
#define DRM_IOCTL_I915_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLUSH)
#define DRM_IOCTL_I915_FLIP DRM_IO(DRM_COMMAND_BASE + DRM_I915_FLIP)
@@ -226,6 +228,8 @@
#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param)
#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param)
+#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config)
+#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64)
typedef struct drm_i915_batchbuffer {
int start;
int used;
@@ -292,6 +296,11 @@
#define I915_PARAM_HUC_STATUS 42
#define I915_PARAM_HAS_EXEC_ASYNC 43
#define I915_PARAM_HAS_EXEC_FENCE 44
+#define I915_PARAM_HAS_EXEC_CAPTURE 45
+#define I915_PARAM_SLICE_MASK 46
+#define I915_PARAM_SUBSLICE_MASK 47
+#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48
+#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49
typedef struct drm_i915_getparam {
__s32 param;
int __user * value;
@@ -396,6 +405,7 @@
#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
#define I915_GEM_DOMAIN_VERTEX 0x00000020
#define I915_GEM_DOMAIN_GTT 0x00000040
+#define I915_GEM_DOMAIN_WC 0x00000080
struct drm_i915_gem_exec_object {
__u32 handle;
__u32 relocation_count;
@@ -426,7 +436,8 @@
#define EXEC_OBJECT_PINNED (1 << 4)
#define EXEC_OBJECT_PAD_TO_SIZE (1 << 5)
#define EXEC_OBJECT_ASYNC (1 << 6)
-#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_ASYNC << 1)
+#define EXEC_OBJECT_CAPTURE (1 << 7)
+#define __EXEC_OBJECT_UNKNOWN_FLAGS - (EXEC_OBJECT_CAPTURE << 1)
__u64 flags;
union {
__u64 rsvd1;
@@ -434,6 +445,13 @@
};
__u64 rsvd2;
};
+struct drm_i915_gem_exec_fence {
+ __u32 handle;
+#define I915_EXEC_FENCE_WAIT (1 << 0)
+#define I915_EXEC_FENCE_SIGNAL (1 << 1)
+#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_SIGNAL << 1))
+ __u32 flags;
+};
struct drm_i915_gem_execbuffer2 {
__u64 buffers_ptr;
__u32 buffer_count;
@@ -470,7 +488,9 @@
#define I915_EXEC_RESOURCE_STREAMER (1 << 15)
#define I915_EXEC_FENCE_IN (1 << 16)
#define I915_EXEC_FENCE_OUT (1 << 17)
-#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_OUT << 1))
+#define I915_EXEC_BATCH_FIRST (1 << 18)
+#define I915_EXEC_FENCE_ARRAY (1 << 19)
+#define __I915_EXEC_UNKNOWN_FLAGS (- (I915_EXEC_FENCE_ARRAY << 1))
#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff)
#define i915_execbuffer2_set_context_id(eb2,context) (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
#define i915_execbuffer2_get_context_id(eb2) ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
@@ -650,6 +670,9 @@
I915_OA_FORMAT_A45_B8_C8,
I915_OA_FORMAT_B4_C8_A16,
I915_OA_FORMAT_C4_B8,
+ I915_OA_FORMAT_A12,
+ I915_OA_FORMAT_A12_B8_C8,
+ I915_OA_FORMAT_A32u40_A4u32_B8_C8,
I915_OA_FORMAT_MAX
};
enum drm_i915_perf_property_id {
@@ -681,6 +704,15 @@
DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3,
DRM_I915_PERF_RECORD_MAX
};
+struct drm_i915_perf_oa_config {
+ char uuid[36];
+ __u32 n_mux_regs;
+ __u32 n_boolean_regs;
+ __u32 n_flex_regs;
+ __u64 __user mux_regs_ptr;
+ __u64 __user boolean_regs_ptr;
+ __u64 __user flex_regs_ptr;
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/msm_drm.h b/libc/kernel/uapi/drm/msm_drm.h
index 83ad769..4f1a423 100644
--- a/libc/kernel/uapi/drm/msm_drm.h
+++ b/libc/kernel/uapi/drm/msm_drm.h
@@ -55,9 +55,11 @@
__u32 flags;
__u32 handle;
};
+#define MSM_INFO_IOVA 0x01
+#define MSM_INFO_FLAGS (MSM_INFO_IOVA)
struct drm_msm_gem_info {
__u32 handle;
- __u32 pad;
+ __u32 flags;
__u64 offset;
};
#define MSM_PREP_READ 0x01
@@ -89,7 +91,7 @@
__u32 size;
__u32 pad;
__u32 nr_relocs;
- __u64 __user relocs;
+ __u64 relocs;
};
#define MSM_SUBMIT_BO_READ 0x0001
#define MSM_SUBMIT_BO_WRITE 0x0002
@@ -108,8 +110,8 @@
__u32 fence;
__u32 nr_bos;
__u32 nr_cmds;
- __u64 __user bos;
- __u64 __user cmds;
+ __u64 bos;
+ __u64 cmds;
__s32 fence_fd;
};
struct drm_msm_wait_fence {
@@ -133,7 +135,6 @@
#define DRM_MSM_GEM_SUBMIT 0x06
#define DRM_MSM_WAIT_FENCE 0x07
#define DRM_MSM_GEM_MADVISE 0x08
-#define DRM_MSM_NUM_IOCTLS 0x09
#define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
#define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
#define DRM_IOCTL_MSM_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info)
diff --git a/libc/kernel/uapi/drm/qxl_drm.h b/libc/kernel/uapi/drm/qxl_drm.h
index c1966ae..5942635 100644
--- a/libc/kernel/uapi/drm/qxl_drm.h
+++ b/libc/kernel/uapi/drm/qxl_drm.h
@@ -51,8 +51,8 @@
__u32 pad;
};
struct drm_qxl_command {
- __u64 __user command;
- __u64 __user relocs;
+ __u64 command;
+ __u64 relocs;
__u32 type;
__u32 command_size;
__u32 relocs_num;
@@ -61,7 +61,7 @@
struct drm_qxl_execbuffer {
__u32 flags;
__u32 commands_num;
- __u64 __user commands;
+ __u64 commands;
};
struct drm_qxl_update_area {
__u32 handle;
diff --git a/libc/kernel/uapi/drm/vc4_drm.h b/libc/kernel/uapi/drm/vc4_drm.h
index 8c59253..d96c49d 100644
--- a/libc/kernel/uapi/drm/vc4_drm.h
+++ b/libc/kernel/uapi/drm/vc4_drm.h
@@ -29,6 +29,9 @@
#define DRM_VC4_CREATE_SHADER_BO 0x05
#define DRM_VC4_GET_HANG_STATE 0x06
#define DRM_VC4_GET_PARAM 0x07
+#define DRM_VC4_SET_TILING 0x08
+#define DRM_VC4_GET_TILING 0x09
+#define DRM_VC4_LABEL_BO 0x0a
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
#define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo)
@@ -37,6 +40,9 @@
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
+#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
+#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
+#define DRM_IOCTL_VC4_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_LABEL_BO, struct drm_vc4_label_bo)
struct drm_vc4_submit_rcl_surface {
__u32 hindex;
__u32 offset;
@@ -71,6 +77,9 @@
__u8 clear_s;
__u32 pad : 24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0)
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y (1 << 3)
__u32 flags;
__u64 seqno;
};
@@ -132,11 +141,27 @@
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
+#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
struct drm_vc4_get_param {
__u32 param;
__u32 pad;
__u64 value;
};
+struct drm_vc4_get_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+struct drm_vc4_set_tiling {
+ __u32 handle;
+ __u32 flags;
+ __u64 modifier;
+};
+struct drm_vc4_label_bo {
+ __u32 handle;
+ __u32 len;
+ __u64 name;
+};
#ifdef __cplusplus
#endif
#endif
diff --git a/libc/kernel/uapi/drm/vmwgfx_drm.h b/libc/kernel/uapi/drm/vmwgfx_drm.h
index 2b7e0fe..f6a7b14 100644
--- a/libc/kernel/uapi/drm/vmwgfx_drm.h
+++ b/libc/kernel/uapi/drm/vmwgfx_drm.h
@@ -104,6 +104,8 @@
struct drm_vmw_surface_arg req;
};
#define DRM_VMW_EXECBUF_VERSION 2
+#define DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD (1 << 0)
+#define DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD (1 << 1)
struct drm_vmw_execbuf_arg {
__u64 commands;
__u32 command_size;
@@ -112,14 +114,14 @@
__u32 version;
__u32 flags;
__u32 context_handle;
- __u32 pad64;
+ __s32 imported_fence_fd;
};
struct drm_vmw_fence_rep {
__u32 handle;
__u32 mask;
__u32 seqno;
__u32 passed_seqno;
- __u32 pad64;
+ __s32 fd;
__s32 error;
};
struct drm_vmw_alloc_dmabuf_req {
diff --git a/libc/kernel/uapi/linux/aio_abi.h b/libc/kernel/uapi/linux/aio_abi.h
index 2a7a6e7..e71936d 100644
--- a/libc/kernel/uapi/linux/aio_abi.h
+++ b/libc/kernel/uapi/linux/aio_abi.h
@@ -19,6 +19,7 @@
#ifndef __LINUX__AIO_ABI_H
#define __LINUX__AIO_ABI_H
#include <linux/types.h>
+#include <linux/fs.h>
#include <asm/byteorder.h>
typedef __kernel_ulong_t aio_context_t;
enum {
@@ -37,16 +38,17 @@
__s64 res;
__s64 res2;
};
+struct iocb {
+ __u64 aio_data;
#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
-#define PADDED(x,y) x, y
+ __u32 aio_key;
+ __kernel_rwf_t aio_rw_flags;
#elif defined(__BYTE_ORDER)?__BYTE_ORDER==__BIG_ENDIAN:defined(__BIG_ENDIAN)
-#define PADDED(x,y) y, x
+ __kernel_rwf_t aio_rw_flags;
+ __u32 aio_key;
#else
#error edit for your odd byteorder .
#endif
-struct iocb {
- __u64 aio_data;
- __u32 PADDED(aio_key, aio_reserved1);
__u16 aio_lio_opcode;
__s16 aio_reqprio;
__u32 aio_fildes;
diff --git a/libc/kernel/uapi/linux/android/binder.h b/libc/kernel/uapi/linux/android/binder.h
index 717826d..538a441 100644
--- a/libc/kernel/uapi/linux/android/binder.h
+++ b/libc/kernel/uapi/linux/android/binder.h
@@ -74,8 +74,9 @@
enum {
BINDER_BUFFER_FLAG_HAS_PARENT = 0x01,
};
-struct __kernel_binder_fd_array_object {
+struct binder_fd_array_object {
struct binder_object_header hdr;
+ __u32 pad;
binder_size_t num_fds;
binder_size_t parent;
binder_size_t parent_offset;
@@ -96,6 +97,12 @@
#else
#define BINDER_CURRENT_PROTOCOL_VERSION 8
#endif
+struct binder_node_debug_info {
+ binder_uintptr_t ptr;
+ binder_uintptr_t cookie;
+ __u32 has_strong_ref;
+ __u32 has_weak_ref;
+};
#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)
@@ -103,6 +110,7 @@
#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)
enum transaction_flags {
TF_ONE_WAY = 0x01,
TF_ROOT_OBJECT = 0x04,
diff --git a/libc/kernel/uapi/linux/auto_dev-ioctl.h b/libc/kernel/uapi/linux/auto_dev-ioctl.h
index be00b9e..23c8096 100644
--- a/libc/kernel/uapi/linux/auto_dev-ioctl.h
+++ b/libc/kernel/uapi/linux/auto_dev-ioctl.h
@@ -22,7 +22,7 @@
#include <linux/string.h>
#define AUTOFS_DEVICE_NAME "autofs"
#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
-#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 1
#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
struct args_protover {
__u32 version;
diff --git a/libc/kernel/uapi/linux/auto_fs4.h b/libc/kernel/uapi/linux/auto_fs4.h
index d09b39b..be6766b 100644
--- a/libc/kernel/uapi/linux/auto_fs4.h
+++ b/libc/kernel/uapi/linux/auto_fs4.h
@@ -85,8 +85,6 @@
AUTOFS_IOC_ASKUMOUNT_CMD = 0x70,
};
#define AUTOFS_IOC_EXPIRE_MULTI _IOW(AUTOFS_IOCTL, AUTOFS_IOC_EXPIRE_MULTI_CMD, int)
-#define AUTOFS_IOC_EXPIRE_INDIRECT AUTOFS_IOC_EXPIRE_MULTI
-#define AUTOFS_IOC_EXPIRE_DIRECT AUTOFS_IOC_EXPIRE_MULTI
#define AUTOFS_IOC_PROTOSUBVER _IOR(AUTOFS_IOCTL, AUTOFS_IOC_PROTOSUBVER_CMD, int)
#define AUTOFS_IOC_ASKUMOUNT _IOR(AUTOFS_IOCTL, AUTOFS_IOC_ASKUMOUNT_CMD, int)
#endif
diff --git a/libc/kernel/uapi/linux/blktrace_api.h b/libc/kernel/uapi/linux/blktrace_api.h
index a6129f8..64c0b77 100644
--- a/libc/kernel/uapi/linux/blktrace_api.h
+++ b/libc/kernel/uapi/linux/blktrace_api.h
@@ -59,11 +59,13 @@
__BLK_TA_REMAP,
__BLK_TA_ABORT,
__BLK_TA_DRV_DATA,
+ __BLK_TA_CGROUP = 1 << 8,
};
enum blktrace_notify {
__BLK_TN_PROCESS = 0,
__BLK_TN_TIMESTAMP,
__BLK_TN_MESSAGE,
+ __BLK_TN_CGROUP = __BLK_TA_CGROUP,
};
#define BLK_TA_QUEUE (__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE))
#define BLK_TA_BACKMERGE (__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
diff --git a/libc/kernel/uapi/linux/bpf.h b/libc/kernel/uapi/linux/bpf.h
index 08c1aba..1dfb99f 100644
--- a/libc/kernel/uapi/linux/bpf.h
+++ b/libc/kernel/uapi/linux/bpf.h
@@ -31,8 +31,12 @@
#define BPF_FROM_LE BPF_TO_LE
#define BPF_FROM_BE BPF_TO_BE
#define BPF_JNE 0x50
+#define BPF_JLT 0xa0
+#define BPF_JLE 0xb0
#define BPF_JSGT 0x60
#define BPF_JSGE 0x70
+#define BPF_JSLT 0xc0
+#define BPF_JSLE 0xd0
#define BPF_CALL 0x80
#define BPF_EXIT 0x90
enum {
@@ -73,6 +77,11 @@
BPF_PROG_ATTACH,
BPF_PROG_DETACH,
BPF_PROG_TEST_RUN,
+ BPF_PROG_GET_NEXT_ID,
+ BPF_MAP_GET_NEXT_ID,
+ BPF_PROG_GET_FD_BY_ID,
+ BPF_MAP_GET_FD_BY_ID,
+ BPF_OBJ_GET_INFO_BY_FD,
};
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC,
@@ -89,6 +98,8 @@
BPF_MAP_TYPE_LPM_TRIE,
BPF_MAP_TYPE_ARRAY_OF_MAPS,
BPF_MAP_TYPE_HASH_OF_MAPS,
+ BPF_MAP_TYPE_DEVMAP,
+ BPF_MAP_TYPE_SOCKMAP,
};
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC,
@@ -104,11 +115,16 @@
BPF_PROG_TYPE_LWT_IN,
BPF_PROG_TYPE_LWT_OUT,
BPF_PROG_TYPE_LWT_XMIT,
+ BPF_PROG_TYPE_SOCK_OPS,
+ BPF_PROG_TYPE_SK_SKB,
};
enum bpf_attach_type {
BPF_CGROUP_INET_INGRESS,
BPF_CGROUP_INET_EGRESS,
BPF_CGROUP_INET_SOCK_CREATE,
+ BPF_CGROUP_SOCK_OPS,
+ BPF_SK_SKB_STREAM_PARSER,
+ BPF_SK_SKB_STREAM_VERDICT,
__MAX_BPF_ATTACH_TYPE
};
#define MAX_BPF_ATTACH_TYPE __MAX_BPF_ATTACH_TYPE
@@ -120,6 +136,7 @@
#define BPF_EXIST 2
#define BPF_F_NO_PREALLOC (1U << 0)
#define BPF_F_NO_COMMON_LRU (1U << 1)
+#define BPF_F_NUMA_NODE (1U << 2)
union bpf_attr {
struct {
__u32 map_type;
@@ -128,6 +145,7 @@
__u32 max_entries;
__u32 map_flags;
__u32 inner_map_fd;
+ __u32 numa_node;
};
struct {
__u32 map_fd;
@@ -169,8 +187,21 @@
__u32 repeat;
__u32 duration;
} test;
+ struct {
+ union {
+ __u32 start_id;
+ __u32 prog_id;
+ __u32 map_id;
+ };
+ __u32 next_id;
+ };
+ struct {
+ __u32 bpf_fd;
+ __u32 info_len;
+ __aligned_u64 info;
+ } info;
} __attribute__((aligned(8)));
-#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid),
+#define __BPF_FUNC_MAPPER(FN) FN(unspec), FN(map_lookup_elem), FN(map_update_elem), FN(map_delete_elem), FN(probe_read), FN(ktime_get_ns), FN(trace_printk), FN(get_prandom_u32), FN(get_smp_processor_id), FN(skb_store_bytes), FN(l3_csum_replace), FN(l4_csum_replace), FN(tail_call), FN(clone_redirect), FN(get_current_pid_tgid), FN(get_current_uid_gid), FN(get_current_comm), FN(get_cgroup_classid), FN(skb_vlan_push), FN(skb_vlan_pop), FN(skb_get_tunnel_key), FN(skb_set_tunnel_key), FN(perf_event_read), FN(redirect), FN(get_route_realm), FN(perf_event_output), FN(skb_load_bytes), FN(get_stackid), FN(csum_diff), FN(skb_get_tunnel_opt), FN(skb_set_tunnel_opt), FN(skb_change_proto), FN(skb_change_type), FN(skb_under_cgroup), FN(get_hash_recalc), FN(get_current_task), FN(probe_write_user), FN(current_task_under_cgroup), FN(skb_change_tail), FN(skb_pull_data), FN(csum_update), FN(set_hash_invalid), FN(get_numa_node_id), FN(skb_change_head), FN(xdp_adjust_head), FN(probe_read_str), FN(get_socket_cookie), FN(get_socket_uid), FN(set_hash), FN(setsockopt), FN(skb_adjust_room), FN(redirect_map), FN(sk_redirect_map), FN(sock_map_update),
#define __BPF_ENUM_FN(x) BPF_FUNC_ ##x
enum bpf_func_id {
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
@@ -193,6 +224,9 @@
#define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
+enum bpf_adj_room_mode {
+ BPF_ADJ_ROOM_NET,
+};
struct __sk_buff {
__u32 len;
__u32 pkt_type;
@@ -212,6 +246,13 @@
__u32 data;
__u32 data_end;
__u32 napi_id;
+ __u32 family;
+ __u32 remote_ip4;
+ __u32 local_ip4;
+ __u32 remote_ip6[4];
+ __u32 local_ip6[4];
+ __u32 remote_port;
+ __u32 local_port;
};
struct bpf_tunnel_key {
__u32 tunnel_id;
@@ -234,6 +275,8 @@
__u32 family;
__u32 type;
__u32 protocol;
+ __u32 mark;
+ __u32 priority;
};
#define XDP_PACKET_HEADROOM 256
enum xdp_action {
@@ -241,9 +284,57 @@
XDP_DROP,
XDP_PASS,
XDP_TX,
+ XDP_REDIRECT,
};
struct xdp_md {
__u32 data;
__u32 data_end;
};
+enum sk_action {
+ SK_DROP = 0,
+ SK_PASS,
+};
+#define BPF_TAG_SIZE 8
+struct bpf_prog_info {
+ __u32 type;
+ __u32 id;
+ __u8 tag[BPF_TAG_SIZE];
+ __u32 jited_prog_len;
+ __u32 xlated_prog_len;
+ __aligned_u64 jited_prog_insns;
+ __aligned_u64 xlated_prog_insns;
+} __attribute__((aligned(8)));
+struct bpf_map_info {
+ __u32 type;
+ __u32 id;
+ __u32 key_size;
+ __u32 value_size;
+ __u32 max_entries;
+ __u32 map_flags;
+} __attribute__((aligned(8)));
+struct bpf_sock_ops {
+ __u32 op;
+ union {
+ __u32 reply;
+ __u32 replylong[4];
+ };
+ __u32 family;
+ __u32 remote_ip4;
+ __u32 local_ip4;
+ __u32 remote_ip6[4];
+ __u32 local_ip6[4];
+ __u32 remote_port;
+ __u32 local_port;
+};
+enum {
+ BPF_SOCK_OPS_VOID,
+ BPF_SOCK_OPS_TIMEOUT_INIT,
+ BPF_SOCK_OPS_RWND_INIT,
+ BPF_SOCK_OPS_TCP_CONNECT_CB,
+ BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
+ BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
+ BPF_SOCK_OPS_NEEDS_ECN,
+};
+#define TCP_BPF_IW 1001
+#define TCP_BPF_SNDCWND_CLAMP 1002
#endif
diff --git a/libc/kernel/uapi/linux/btrfs.h b/libc/kernel/uapi/linux/btrfs.h
index 56e33ae..a23ab58 100644
--- a/libc/kernel/uapi/linux/btrfs.h
+++ b/libc/kernel/uapi/linux/btrfs.h
@@ -167,7 +167,7 @@
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3)
-#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4)
+#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD (1ULL << 4)
#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5)
#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
diff --git a/libc/kernel/uapi/linux/capability.h b/libc/kernel/uapi/linux/capability.h
index f414848..8ba448e 100644
--- a/libc/kernel/uapi/linux/capability.h
+++ b/libc/kernel/uapi/linux/capability.h
@@ -44,9 +44,12 @@
#define VFS_CAP_REVISION_2 0x02000000
#define VFS_CAP_U32_2 2
#define XATTR_CAPS_SZ_2 (sizeof(__le32) * (1 + 2 * VFS_CAP_U32_2))
-#define XATTR_CAPS_SZ XATTR_CAPS_SZ_2
-#define VFS_CAP_U32 VFS_CAP_U32_2
-#define VFS_CAP_REVISION VFS_CAP_REVISION_2
+#define VFS_CAP_REVISION_3 0x03000000
+#define VFS_CAP_U32_3 2
+#define XATTR_CAPS_SZ_3 (sizeof(__le32) * (2 + 2 * VFS_CAP_U32_3))
+#define XATTR_CAPS_SZ XATTR_CAPS_SZ_3
+#define VFS_CAP_U32 VFS_CAP_U32_3
+#define VFS_CAP_REVISION VFS_CAP_REVISION_3
struct vfs_cap_data {
__le32 magic_etc;
struct {
@@ -54,6 +57,14 @@
__le32 inheritable;
} data[VFS_CAP_U32];
};
+struct vfs_ns_cap_data {
+ __le32 magic_etc;
+ struct {
+ __le32 permitted;
+ __le32 inheritable;
+ } data[VFS_CAP_U32];
+ __le32 rootid;
+};
#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1
#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1
#define CAP_CHOWN 0
diff --git a/libc/kernel/uapi/linux/cec.h b/libc/kernel/uapi/linux/cec.h
index 8125ac4..3fcee96 100644
--- a/libc/kernel/uapi/linux/cec.h
+++ b/libc/kernel/uapi/linux/cec.h
@@ -91,6 +91,7 @@
#define CEC_MODE_FOLLOWER (0x1 << 4)
#define CEC_MODE_EXCL_FOLLOWER (0x2 << 4)
#define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4)
+#define CEC_MODE_MONITOR_PIN (0xd << 4)
#define CEC_MODE_MONITOR (0xe << 4)
#define CEC_MODE_MONITOR_ALL (0xf << 4)
#define CEC_MODE_FOLLOWER_MSK 0xf0
@@ -100,6 +101,8 @@
#define CEC_CAP_PASSTHROUGH (1 << 3)
#define CEC_CAP_RC (1 << 4)
#define CEC_CAP_MONITOR_ALL (1 << 5)
+#define CEC_CAP_NEEDS_HPD (1 << 6)
+#define CEC_CAP_MONITOR_PIN (1 << 7)
struct cec_caps {
char driver[32];
char name[32];
@@ -125,7 +128,10 @@
#define CEC_LOG_ADDRS_FL_CDC_ONLY (1 << 2)
#define CEC_EVENT_STATE_CHANGE 1
#define CEC_EVENT_LOST_MSGS 2
+#define CEC_EVENT_PIN_CEC_LOW 3
+#define CEC_EVENT_PIN_CEC_HIGH 4
#define CEC_EVENT_FL_INITIAL_STATE (1 << 0)
+#define CEC_EVENT_FL_DROPPED_EVENTS (1 << 1)
struct cec_event_state_change {
__u16 phys_addr;
__u16 log_addr_mask;
diff --git a/libc/kernel/uapi/linux/devlink.h b/libc/kernel/uapi/linux/devlink.h
index 01f6e74..1d5c43c 100644
--- a/libc/kernel/uapi/linux/devlink.h
+++ b/libc/kernel/uapi/linux/devlink.h
@@ -168,4 +168,18 @@
enum devlink_dpipe_action_type {
DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY,
};
+enum devlink_dpipe_field_ethernet_id {
+ DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
+};
+enum devlink_dpipe_field_ipv4_id {
+ DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
+};
+enum devlink_dpipe_field_ipv6_id {
+ DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
+};
+enum devlink_dpipe_header_id {
+ DEVLINK_DPIPE_HEADER_ETHERNET,
+ DEVLINK_DPIPE_HEADER_IPV4,
+ DEVLINK_DPIPE_HEADER_IPV6,
+};
#endif
diff --git a/libc/kernel/uapi/linux/dlm_netlink.h b/libc/kernel/uapi/linux/dlm_netlink.h
index 64e5d1e..0c655fa 100644
--- a/libc/kernel/uapi/linux/dlm_netlink.h
+++ b/libc/kernel/uapi/linux/dlm_netlink.h
@@ -19,6 +19,7 @@
#ifndef _DLM_NETLINK_H
#define _DLM_NETLINK_H
#include <linux/types.h>
+#include <linux/dlmconstants.h>
enum {
DLM_STATUS_WAITING = 1,
DLM_STATUS_GRANTED = 2,
diff --git a/libc/kernel/uapi/linux/dm-ioctl.h b/libc/kernel/uapi/linux/dm-ioctl.h
index a418ea0..cc340b5 100644
--- a/libc/kernel/uapi/linux/dm-ioctl.h
+++ b/libc/kernel/uapi/linux/dm-ioctl.h
@@ -80,7 +80,8 @@
DM_TABLE_STATUS_CMD,
DM_LIST_VERSIONS_CMD,
DM_TARGET_MSG_CMD,
- DM_DEV_SET_GEOMETRY_CMD
+ DM_DEV_SET_GEOMETRY_CMD,
+ DM_DEV_ARM_POLL_CMD,
};
#define DM_IOCTL 0xfd
#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
@@ -92,6 +93,7 @@
#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+#define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_ARM_POLL_CMD, struct dm_ioctl)
#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
@@ -100,9 +102,9 @@
#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 35
+#define DM_VERSION_MINOR 37
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl(2016-06-23)"
+#define DM_VERSION_EXTRA "-ioctl(2017-09-20)"
#define DM_READONLY_FLAG (1 << 0)
#define DM_SUSPEND_FLAG (1 << 1)
#define DM_PERSISTENT_DEV_FLAG (1 << 3)
diff --git a/libc/kernel/uapi/linux/dvb/ca.h b/libc/kernel/uapi/linux/dvb/ca.h
index c494ad5..fa977c7 100644
--- a/libc/kernel/uapi/linux/dvb/ca.h
+++ b/libc/kernel/uapi/linux/dvb/ca.h
@@ -18,7 +18,7 @@
****************************************************************************/
#ifndef _DVBCA_H_
#define _DVBCA_H_
-typedef struct ca_slot_info {
+struct ca_slot_info {
int num;
int type;
#define CA_CI 1
@@ -29,41 +29,41 @@
unsigned int flags;
#define CA_CI_MODULE_PRESENT 1
#define CA_CI_MODULE_READY 2
-} ca_slot_info_t;
-typedef struct ca_descr_info {
+};
+struct ca_descr_info {
unsigned int num;
unsigned int type;
#define CA_ECD 1
#define CA_NDS 2
#define CA_DSS 4
-} ca_descr_info_t;
-typedef struct ca_caps {
+};
+struct ca_caps {
unsigned int slot_num;
unsigned int slot_type;
unsigned int descr_num;
unsigned int descr_type;
-} ca_caps_t;
-typedef struct ca_msg {
+};
+struct ca_msg {
unsigned int index;
unsigned int type;
unsigned int length;
unsigned char msg[256];
-} ca_msg_t;
-typedef struct ca_descr {
+};
+struct ca_descr {
unsigned int index;
unsigned int parity;
unsigned char cw[8];
-} ca_descr_t;
-typedef struct ca_pid {
- unsigned int pid;
- int index;
-} ca_pid_t;
+};
#define CA_RESET _IO('o', 128)
-#define CA_GET_CAP _IOR('o', 129, ca_caps_t)
-#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t)
-#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
-#define CA_GET_MSG _IOR('o', 132, ca_msg_t)
-#define CA_SEND_MSG _IOW('o', 133, ca_msg_t)
-#define CA_SET_DESCR _IOW('o', 134, ca_descr_t)
-#define CA_SET_PID _IOW('o', 135, ca_pid_t)
+#define CA_GET_CAP _IOR('o', 129, struct ca_caps)
+#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info)
+#define CA_GET_DESCR_INFO _IOR('o', 131, struct ca_descr_info)
+#define CA_GET_MSG _IOR('o', 132, struct ca_msg)
+#define CA_SEND_MSG _IOW('o', 133, struct ca_msg)
+#define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
+typedef struct ca_slot_info ca_slot_info_t;
+typedef struct ca_descr_info ca_descr_info_t;
+typedef struct ca_caps ca_caps_t;
+typedef struct ca_msg ca_msg_t;
+typedef struct ca_descr ca_descr_t;
#endif
diff --git a/libc/kernel/uapi/linux/dvb/dmx.h b/libc/kernel/uapi/linux/dvb/dmx.h
index 438c832..d4ea26e 100644
--- a/libc/kernel/uapi/linux/dvb/dmx.h
+++ b/libc/kernel/uapi/linux/dvb/dmx.h
@@ -27,12 +27,11 @@
DMX_OUT_TS_TAP,
DMX_OUT_TSDEMUX_TAP
};
-typedef enum dmx_output dmx_output_t;
-typedef enum dmx_input {
+enum dmx_input {
DMX_IN_FRONTEND,
DMX_IN_DVR
-} dmx_input_t;
-typedef enum dmx_ts_pes {
+};
+enum dmx_ts_pes {
DMX_PES_AUDIO0,
DMX_PES_VIDEO0,
DMX_PES_TELETEXT0,
@@ -54,48 +53,33 @@
DMX_PES_SUBTITLE3,
DMX_PES_PCR3,
DMX_PES_OTHER
-} dmx_pes_type_t;
+};
#define DMX_PES_AUDIO DMX_PES_AUDIO0
#define DMX_PES_VIDEO DMX_PES_VIDEO0
#define DMX_PES_TELETEXT DMX_PES_TELETEXT0
#define DMX_PES_SUBTITLE DMX_PES_SUBTITLE0
#define DMX_PES_PCR DMX_PES_PCR0
-typedef struct dmx_filter {
+struct dmx_filter {
__u8 filter[DMX_FILTER_SIZE];
__u8 mask[DMX_FILTER_SIZE];
__u8 mode[DMX_FILTER_SIZE];
-} dmx_filter_t;
+};
struct dmx_sct_filter_params {
__u16 pid;
- dmx_filter_t filter;
+ struct dmx_filter filter;
__u32 timeout;
__u32 flags;
#define DMX_CHECK_CRC 1
#define DMX_ONESHOT 2
#define DMX_IMMEDIATE_START 4
-#define DMX_KERNEL_CLIENT 0x8000
};
struct dmx_pes_filter_params {
__u16 pid;
- dmx_input_t input;
- dmx_output_t output;
- dmx_pes_type_t pes_type;
+ enum dmx_input input;
+ enum dmx_output output;
+ enum dmx_ts_pes pes_type;
__u32 flags;
};
-typedef struct dmx_caps {
- __u32 caps;
- int num_decoders;
-} dmx_caps_t;
-typedef enum dmx_source {
- DMX_SOURCE_FRONT0 = 0,
- DMX_SOURCE_FRONT1,
- DMX_SOURCE_FRONT2,
- DMX_SOURCE_FRONT3,
- DMX_SOURCE_DVR0 = 16,
- DMX_SOURCE_DVR1,
- DMX_SOURCE_DVR2,
- DMX_SOURCE_DVR3
-} dmx_source_t;
struct dmx_stc {
unsigned int num;
unsigned int base;
@@ -107,9 +91,11 @@
#define DMX_SET_PES_FILTER _IOW('o', 44, struct dmx_pes_filter_params)
#define DMX_SET_BUFFER_SIZE _IO('o', 45)
#define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5])
-#define DMX_GET_CAPS _IOR('o', 48, dmx_caps_t)
-#define DMX_SET_SOURCE _IOW('o', 49, dmx_source_t)
#define DMX_GET_STC _IOWR('o', 50, struct dmx_stc)
#define DMX_ADD_PID _IOW('o', 51, __u16)
#define DMX_REMOVE_PID _IOW('o', 52, __u16)
+typedef enum dmx_output dmx_output_t;
+typedef enum dmx_input dmx_input_t;
+typedef enum dmx_ts_pes dmx_pes_type_t;
+typedef struct dmx_filter dmx_filter_t;
#endif
diff --git a/libc/kernel/uapi/linux/dvb/frontend.h b/libc/kernel/uapi/linux/dvb/frontend.h
index 387e3f1..c8a48c1 100644
--- a/libc/kernel/uapi/linux/dvb/frontend.h
+++ b/libc/kernel/uapi/linux/dvb/frontend.h
@@ -19,12 +19,6 @@
#ifndef _DVBFRONTEND_H_
#define _DVBFRONTEND_H_
#include <linux/types.h>
-enum fe_type {
- FE_QPSK,
- FE_QAM,
- FE_OFDM,
- FE_ATSC
-};
enum fe_caps {
FE_IS_STUPID = 0,
FE_CAN_INVERSION_AUTO = 0x1,
@@ -58,6 +52,12 @@
FE_CAN_RECOVER = 0x40000000,
FE_CAN_MUTE_TS = 0x80000000
};
+enum fe_type {
+ FE_QPSK,
+ FE_QAM,
+ FE_OFDM,
+ FE_ATSC
+};
struct dvb_frontend_info {
char name[128];
enum fe_type type;
@@ -94,6 +94,7 @@
SEC_MINI_B
};
enum fe_status {
+ FE_NONE = 0x00,
FE_HAS_SIGNAL = 0x01,
FE_HAS_CARRIER = 0x02,
FE_HAS_VITERBI = 0x04,
@@ -308,13 +309,6 @@
};
#define NO_STREAM_ID_FILTER (~0U)
#define LNA_AUTO (~0U)
-struct dtv_cmds_h {
- char * name;
- __u32 cmd;
- __u32 set : 1;
- __u32 buffer : 1;
- __u32 reserved : 30;
-};
enum fecap_scale_params {
FE_SCALE_NOT_AVAILABLE = 0,
FE_SCALE_DECIBEL,
@@ -353,6 +347,25 @@
__u32 num;
struct dtv_property * props;
};
+#define FE_TUNE_MODE_ONESHOT 0x01
+#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
+#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
+#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
+#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
+#define FE_DISEQC_SEND_BURST _IO('o', 65)
+#define FE_SET_TONE _IO('o', 66)
+#define FE_SET_VOLTAGE _IO('o', 67)
+#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68)
+#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
+#define FE_READ_BER _IOR('o', 70, __u32)
+#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
+#define FE_READ_SNR _IOR('o', 72, __u16)
+#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
+#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81)
+#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
+#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80)
+#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
+#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
enum fe_bandwidth {
BANDWIDTH_8_MHZ,
BANDWIDTH_7_MHZ,
@@ -413,25 +426,6 @@
fe_status_t status;
struct dvb_frontend_parameters parameters;
};
-#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
-#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
-#define FE_TUNE_MODE_ONESHOT 0x01
-#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
-#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
-#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
-#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
-#define FE_DISEQC_SEND_BURST _IO('o', 65)
-#define FE_SET_TONE _IO('o', 66)
-#define FE_SET_VOLTAGE _IO('o', 67)
-#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68)
-#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
-#define FE_READ_BER _IOR('o', 70, __u32)
-#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
-#define FE_READ_SNR _IOR('o', 72, __u16)
-#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
-#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81)
-#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
-#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80)
#endif
diff --git a/libc/kernel/uapi/linux/dvb/video.h b/libc/kernel/uapi/linux/dvb/video.h
index e235114..7ada1a0 100644
--- a/libc/kernel/uapi/linux/dvb/video.h
+++ b/libc/kernel/uapi/linux/dvb/video.h
@@ -89,7 +89,7 @@
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
#define VIDEO_EVENT_DECODER_STOPPED 3
#define VIDEO_EVENT_VSYNC 4
- __kernel_time_t timestamp;
+ long timestamp;
union {
video_size_t size;
unsigned int frame_rate;
diff --git a/libc/kernel/uapi/linux/errqueue.h b/libc/kernel/uapi/linux/errqueue.h
index 5daeb10..196189b 100644
--- a/libc/kernel/uapi/linux/errqueue.h
+++ b/libc/kernel/uapi/linux/errqueue.h
@@ -33,8 +33,10 @@
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3
#define SO_EE_ORIGIN_TXSTATUS 4
+#define SO_EE_ORIGIN_ZEROCOPY 5
#define SO_EE_ORIGIN_TIMESTAMPING SO_EE_ORIGIN_TXSTATUS
#define SO_EE_OFFENDER(ee) ((struct sockaddr *) ((ee) + 1))
+#define SO_EE_CODE_ZEROCOPY_COPIED 1
struct scm_timestamping {
struct timespec ts[3];
};
diff --git a/libc/kernel/uapi/linux/ethtool.h b/libc/kernel/uapi/linux/ethtool.h
index 56df94b..6f1c0f3 100644
--- a/libc/kernel/uapi/linux/ethtool.h
+++ b/libc/kernel/uapi/linux/ethtool.h
@@ -418,6 +418,24 @@
__u32 queue_mask[__KERNEL_DIV_ROUND_UP(MAX_NUM_QUEUE, 32)];
char data[];
};
+struct ethtool_fecparam {
+ __u32 cmd;
+ __u32 active_fec;
+ __u32 fec;
+ __u32 reserved;
+};
+enum ethtool_fec_config_bits {
+ ETHTOOL_FEC_NONE_BIT,
+ ETHTOOL_FEC_AUTO_BIT,
+ ETHTOOL_FEC_OFF_BIT,
+ ETHTOOL_FEC_RS_BIT,
+ ETHTOOL_FEC_BASER_BIT,
+};
+#define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT)
+#define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT)
+#define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT)
+#define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT)
+#define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT)
#define ETHTOOL_GSET 0x00000001
#define ETHTOOL_SSET 0x00000002
#define ETHTOOL_GDRVINFO 0x00000003
@@ -496,6 +514,8 @@
#define ETHTOOL_SLINKSETTINGS 0x0000004d
#define ETHTOOL_PHY_GTUNABLE 0x0000004e
#define ETHTOOL_PHY_STUNABLE 0x0000004f
+#define ETHTOOL_GFECPARAM 0x00000050
+#define ETHTOOL_SFECPARAM 0x00000051
#define SPARC_ETH_GSET ETHTOOL_GSET
#define SPARC_ETH_SSET ETHTOOL_SSET
enum ethtool_link_mode_bit_indices {
@@ -548,7 +568,10 @@
ETHTOOL_LINK_MODE_10000baseER_Full_BIT = 46,
ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47,
ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48,
- __ETHTOOL_LINK_MODE_LAST = ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_FEC_NONE_BIT = 49,
+ ETHTOOL_LINK_MODE_FEC_RS_BIT = 50,
+ ETHTOOL_LINK_MODE_FEC_BASER_BIT = 51,
+ __ETHTOOL_LINK_MODE_LAST = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
};
#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) (1UL << (ETHTOOL_LINK_MODE_ ##base_name ##_BIT))
#define SUPPORTED_10baseT_Half __ETHTOOL_LINK_MODE_LEGACY_MASK(10baseT_Half)
@@ -721,7 +744,9 @@
__u8 eth_tp_mdix;
__u8 eth_tp_mdix_ctrl;
__s8 link_mode_masks_nwords;
- __u32 reserved[8];
+ __u8 transceiver;
+ __u8 reserved1[3];
+ __u32 reserved[7];
__u32 link_mode_masks[0];
};
#endif
diff --git a/libc/kernel/uapi/linux/fcntl.h b/libc/kernel/uapi/linux/fcntl.h
index c4a8314..e98a67b 100644
--- a/libc/kernel/uapi/linux/fcntl.h
+++ b/libc/kernel/uapi/linux/fcntl.h
@@ -32,6 +32,16 @@
#define F_SEAL_SHRINK 0x0002
#define F_SEAL_GROW 0x0004
#define F_SEAL_WRITE 0x0008
+#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11)
+#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12)
+#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13)
+#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14)
+#define RWF_WRITE_LIFE_NOT_SET 0
+#define RWH_WRITE_LIFE_NONE 1
+#define RWH_WRITE_LIFE_SHORT 2
+#define RWH_WRITE_LIFE_MEDIUM 3
+#define RWH_WRITE_LIFE_LONG 4
+#define RWH_WRITE_LIFE_EXTREME 5
#define DN_ACCESS 0x00000001
#define DN_MODIFY 0x00000002
#define DN_CREATE 0x00000004
diff --git a/libc/kernel/uapi/linux/fs.h b/libc/kernel/uapi/linux/fs.h
index 75c17a4..f4e74cd 100644
--- a/libc/kernel/uapi/linux/fs.h
+++ b/libc/kernel/uapi/linux/fs.h
@@ -193,6 +193,8 @@
#define FS_ENCRYPTION_MODE_AES_256_GCM 2
#define FS_ENCRYPTION_MODE_AES_256_CBC 3
#define FS_ENCRYPTION_MODE_AES_256_CTS 4
+#define FS_ENCRYPTION_MODE_AES_128_CBC 5
+#define FS_ENCRYPTION_MODE_AES_128_CTS 6
struct fscrypt_policy {
__u8 version;
__u8 contents_encryption_mode;
@@ -243,7 +245,10 @@
#define SYNC_FILE_RANGE_WAIT_BEFORE 1
#define SYNC_FILE_RANGE_WRITE 2
#define SYNC_FILE_RANGE_WAIT_AFTER 4
-#define RWF_HIPRI 0x00000001
-#define RWF_DSYNC 0x00000002
-#define RWF_SYNC 0x00000004
+typedef int __bitwise __kernel_rwf_t;
+#define RWF_HIPRI ((__force __kernel_rwf_t) 0x00000001)
+#define RWF_DSYNC ((__force __kernel_rwf_t) 0x00000002)
+#define RWF_SYNC ((__force __kernel_rwf_t) 0x00000004)
+#define RWF_NOWAIT ((__force __kernel_rwf_t) 0x00000008)
+#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT)
#endif
diff --git a/libc/kernel/uapi/linux/if_arp.h b/libc/kernel/uapi/linux/if_arp.h
index 9f056fb..0b1959d 100644
--- a/libc/kernel/uapi/linux/if_arp.h
+++ b/libc/kernel/uapi/linux/if_arp.h
@@ -50,6 +50,7 @@
#define ARPHRD_LAPB 516
#define ARPHRD_DDCMP 517
#define ARPHRD_RAWHDLC 518
+#define ARPHRD_RAWIP 519
#define ARPHRD_TUNNEL 768
#define ARPHRD_TUNNEL6 769
#define ARPHRD_FRAD 770
diff --git a/libc/kernel/uapi/linux/if_ether.h b/libc/kernel/uapi/linux/if_ether.h
index 846d238..f40321e 100644
--- a/libc/kernel/uapi/linux/if_ether.h
+++ b/libc/kernel/uapi/linux/if_ether.h
@@ -51,6 +51,7 @@
#define ETH_P_ATALK 0x809B
#define ETH_P_AARP 0x80F3
#define ETH_P_8021Q 0x8100
+#define ETH_P_ERSPAN 0x88BE
#define ETH_P_IPX 0x8137
#define ETH_P_IPV6 0x86DD
#define ETH_P_PAUSE 0x8808
@@ -80,11 +81,13 @@
#define ETH_P_FIP 0x8914
#define ETH_P_80221 0x8917
#define ETH_P_HSR 0x892F
+#define ETH_P_NSH 0x894F
#define ETH_P_LOOPBACK 0x9000
#define ETH_P_QINQ1 0x9100
#define ETH_P_QINQ2 0x9200
#define ETH_P_QINQ3 0x9300
#define ETH_P_EDSA 0xDADA
+#define ETH_P_IFE 0xED3E
#define ETH_P_AF_IUCV 0xFBFB
#define ETH_P_802_3_MIN 0x0600
#define ETH_P_802_3 0x0001
@@ -112,6 +115,7 @@
#define ETH_P_IEEE802154 0x00F6
#define ETH_P_CAIF 0x00F7
#define ETH_P_XDSA 0x00F8
+#define ETH_P_MAP 0x00F9
struct ethhdr {
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
diff --git a/libc/kernel/uapi/linux/if_link.h b/libc/kernel/uapi/linux/if_link.h
index 8ea790b..c041c82 100644
--- a/libc/kernel/uapi/linux/if_link.h
+++ b/libc/kernel/uapi/linux/if_link.h
@@ -135,6 +135,7 @@
IFLA_GSO_MAX_SIZE,
IFLA_PAD,
IFLA_XDP,
+ IFLA_EVENT,
__IFLA_MAX
};
#define IFLA_MAX (__IFLA_MAX - 1)
@@ -693,18 +694,31 @@
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
#define XDP_FLAGS_SKB_MODE (1U << 1)
#define XDP_FLAGS_DRV_MODE (1U << 2)
-#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE)
+#define XDP_FLAGS_HW_MODE (1U << 3)
+#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | XDP_FLAGS_DRV_MODE | XDP_FLAGS_HW_MODE)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_MODES)
enum {
XDP_ATTACHED_NONE = 0,
XDP_ATTACHED_DRV,
XDP_ATTACHED_SKB,
+ XDP_ATTACHED_HW,
};
enum {
IFLA_XDP_UNSPEC,
IFLA_XDP_FD,
IFLA_XDP_ATTACHED,
IFLA_XDP_FLAGS,
+ IFLA_XDP_PROG_ID,
__IFLA_XDP_MAX,
};
#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+enum {
+ IFLA_EVENT_NONE,
+ IFLA_EVENT_REBOOT,
+ IFLA_EVENT_FEATURES,
+ IFLA_EVENT_BONDING_FAILOVER,
+ IFLA_EVENT_NOTIFY_PEERS,
+ IFLA_EVENT_IGMP_RESEND,
+ IFLA_EVENT_BONDING_OPTIONS,
+};
#endif
diff --git a/libc/kernel/uapi/linux/if_tunnel.h b/libc/kernel/uapi/linux/if_tunnel.h
index aaad4cb..bfc6479 100644
--- a/libc/kernel/uapi/linux/if_tunnel.h
+++ b/libc/kernel/uapi/linux/if_tunnel.h
@@ -134,6 +134,7 @@
IFLA_GRE_COLLECT_METADATA,
IFLA_GRE_IGNORE_DF,
IFLA_GRE_FWMARK,
+ IFLA_GRE_ERSPAN_INDEX,
__IFLA_GRE_MAX,
};
#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1)
diff --git a/libc/kernel/uapi/linux/inet_diag.h b/libc/kernel/uapi/linux/inet_diag.h
index 9753de0..47a3b34 100644
--- a/libc/kernel/uapi/linux/inet_diag.h
+++ b/libc/kernel/uapi/linux/inet_diag.h
@@ -119,6 +119,8 @@
INET_DIAG_PAD,
INET_DIAG_MARK,
INET_DIAG_BBRINFO,
+ INET_DIAG_CLASS_ID,
+ INET_DIAG_MD5SIG,
__INET_DIAG_MAX,
};
#define INET_DIAG_MAX (__INET_DIAG_MAX - 1)
diff --git a/libc/kernel/uapi/linux/input-event-codes.h b/libc/kernel/uapi/linux/input-event-codes.h
index aea69f3..346ec91 100644
--- a/libc/kernel/uapi/linux/input-event-codes.h
+++ b/libc/kernel/uapi/linux/input-event-codes.h
@@ -538,6 +538,7 @@
#define KEY_APPSELECT 0x244
#define KEY_SCREENSAVER 0x245
#define KEY_VOICECOMMAND 0x246
+#define KEY_ASSISTANT 0x247
#define KEY_BRIGHTNESS_MIN 0x250
#define KEY_BRIGHTNESS_MAX 0x251
#define KEY_KBDINPUTASSIST_PREV 0x260
diff --git a/libc/kernel/uapi/linux/kcmp.h b/libc/kernel/uapi/linux/kcmp.h
index 53064b1..d185c0a 100644
--- a/libc/kernel/uapi/linux/kcmp.h
+++ b/libc/kernel/uapi/linux/kcmp.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _UAPI_LINUX_KCMP_H
#define _UAPI_LINUX_KCMP_H
+#include <linux/types.h>
enum kcmp_type {
KCMP_FILE,
KCMP_VM,
@@ -26,6 +27,12 @@
KCMP_SIGHAND,
KCMP_IO,
KCMP_SYSVSEM,
+ KCMP_EPOLL_TFD,
KCMP_TYPES,
};
+struct kcmp_epoll_slot {
+ __u32 efd;
+ __u32 tfd;
+ __u32 toff;
+};
#endif
diff --git a/libc/kernel/uapi/linux/kfd_ioctl.h b/libc/kernel/uapi/linux/kfd_ioctl.h
index 79e5c01..f870cd6 100644
--- a/libc/kernel/uapi/linux/kfd_ioctl.h
+++ b/libc/kernel/uapi/linux/kfd_ioctl.h
@@ -18,13 +18,13 @@
****************************************************************************/
#ifndef KFD_IOCTL_H_INCLUDED
#define KFD_IOCTL_H_INCLUDED
-#include <linux/types.h>
+#include <drm/drm.h>
#include <linux/ioctl.h>
#define KFD_IOCTL_MAJOR_VERSION 1
#define KFD_IOCTL_MINOR_VERSION 1
struct kfd_ioctl_get_version_args {
- uint32_t major_version;
- uint32_t minor_version;
+ __u32 major_version;
+ __u32 minor_version;
};
#define KFD_IOC_QUEUE_TYPE_COMPUTE 0
#define KFD_IOC_QUEUE_TYPE_SDMA 1
@@ -32,86 +32,86 @@
#define KFD_MAX_QUEUE_PERCENTAGE 100
#define KFD_MAX_QUEUE_PRIORITY 15
struct kfd_ioctl_create_queue_args {
- uint64_t ring_base_address;
- uint64_t write_pointer_address;
- uint64_t read_pointer_address;
- uint64_t doorbell_offset;
- uint32_t ring_size;
- uint32_t gpu_id;
- uint32_t queue_type;
- uint32_t queue_percentage;
- uint32_t queue_priority;
- uint32_t queue_id;
- uint64_t eop_buffer_address;
- uint64_t eop_buffer_size;
- uint64_t ctx_save_restore_address;
- uint64_t ctx_save_restore_size;
+ __u64 ring_base_address;
+ __u64 write_pointer_address;
+ __u64 read_pointer_address;
+ __u64 doorbell_offset;
+ __u32 ring_size;
+ __u32 gpu_id;
+ __u32 queue_type;
+ __u32 queue_percentage;
+ __u32 queue_priority;
+ __u32 queue_id;
+ __u64 eop_buffer_address;
+ __u64 eop_buffer_size;
+ __u64 ctx_save_restore_address;
+ __u64 ctx_save_restore_size;
};
struct kfd_ioctl_destroy_queue_args {
- uint32_t queue_id;
- uint32_t pad;
+ __u32 queue_id;
+ __u32 pad;
};
struct kfd_ioctl_update_queue_args {
- uint64_t ring_base_address;
- uint32_t queue_id;
- uint32_t ring_size;
- uint32_t queue_percentage;
- uint32_t queue_priority;
+ __u64 ring_base_address;
+ __u32 queue_id;
+ __u32 ring_size;
+ __u32 queue_percentage;
+ __u32 queue_priority;
};
#define KFD_IOC_CACHE_POLICY_COHERENT 0
#define KFD_IOC_CACHE_POLICY_NONCOHERENT 1
struct kfd_ioctl_set_memory_policy_args {
- uint64_t alternate_aperture_base;
- uint64_t alternate_aperture_size;
- uint32_t gpu_id;
- uint32_t default_policy;
- uint32_t alternate_policy;
- uint32_t pad;
+ __u64 alternate_aperture_base;
+ __u64 alternate_aperture_size;
+ __u32 gpu_id;
+ __u32 default_policy;
+ __u32 alternate_policy;
+ __u32 pad;
};
struct kfd_ioctl_get_clock_counters_args {
- uint64_t gpu_clock_counter;
- uint64_t cpu_clock_counter;
- uint64_t system_clock_counter;
- uint64_t system_clock_freq;
- uint32_t gpu_id;
- uint32_t pad;
+ __u64 gpu_clock_counter;
+ __u64 cpu_clock_counter;
+ __u64 system_clock_counter;
+ __u64 system_clock_freq;
+ __u32 gpu_id;
+ __u32 pad;
};
#define NUM_OF_SUPPORTED_GPUS 7
struct kfd_process_device_apertures {
- uint64_t lds_base;
- uint64_t lds_limit;
- uint64_t scratch_base;
- uint64_t scratch_limit;
- uint64_t gpuvm_base;
- uint64_t gpuvm_limit;
- uint32_t gpu_id;
- uint32_t pad;
+ __u64 lds_base;
+ __u64 lds_limit;
+ __u64 scratch_base;
+ __u64 scratch_limit;
+ __u64 gpuvm_base;
+ __u64 gpuvm_limit;
+ __u32 gpu_id;
+ __u32 pad;
};
struct kfd_ioctl_get_process_apertures_args {
struct kfd_process_device_apertures process_apertures[NUM_OF_SUPPORTED_GPUS];
- uint32_t num_of_nodes;
- uint32_t pad;
+ __u32 num_of_nodes;
+ __u32 pad;
};
#define MAX_ALLOWED_NUM_POINTS 100
#define MAX_ALLOWED_AW_BUFF_SIZE 4096
#define MAX_ALLOWED_WAC_BUFF_SIZE 128
struct kfd_ioctl_dbg_register_args {
- uint32_t gpu_id;
- uint32_t pad;
+ __u32 gpu_id;
+ __u32 pad;
};
struct kfd_ioctl_dbg_unregister_args {
- uint32_t gpu_id;
- uint32_t pad;
+ __u32 gpu_id;
+ __u32 pad;
};
struct kfd_ioctl_dbg_address_watch_args {
- uint64_t content_ptr;
- uint32_t gpu_id;
- uint32_t buf_size_in_bytes;
+ __u64 content_ptr;
+ __u32 gpu_id;
+ __u32 buf_size_in_bytes;
};
struct kfd_ioctl_dbg_wave_control_args {
- uint64_t content_ptr;
- uint32_t gpu_id;
- uint32_t buf_size_in_bytes;
+ __u64 content_ptr;
+ __u32 gpu_id;
+ __u32 buf_size_in_bytes;
};
#define KFD_IOC_EVENT_SIGNAL 0
#define KFD_IOC_EVENT_NODECHANGE 1
@@ -127,52 +127,67 @@
#define KFD_IOC_WAIT_RESULT_FAIL 2
#define KFD_SIGNAL_EVENT_LIMIT 256
struct kfd_ioctl_create_event_args {
- uint64_t event_page_offset;
- uint32_t event_trigger_data;
- uint32_t event_type;
- uint32_t auto_reset;
- uint32_t node_id;
- uint32_t event_id;
- uint32_t event_slot_index;
+ __u64 event_page_offset;
+ __u32 event_trigger_data;
+ __u32 event_type;
+ __u32 auto_reset;
+ __u32 node_id;
+ __u32 event_id;
+ __u32 event_slot_index;
};
struct kfd_ioctl_destroy_event_args {
- uint32_t event_id;
- uint32_t pad;
+ __u32 event_id;
+ __u32 pad;
};
struct kfd_ioctl_set_event_args {
- uint32_t event_id;
- uint32_t pad;
+ __u32 event_id;
+ __u32 pad;
};
struct kfd_ioctl_reset_event_args {
- uint32_t event_id;
- uint32_t pad;
+ __u32 event_id;
+ __u32 pad;
};
struct kfd_memory_exception_failure {
- uint32_t NotPresent;
- uint32_t ReadOnly;
- uint32_t NoExecute;
- uint32_t pad;
+ __u32 NotPresent;
+ __u32 ReadOnly;
+ __u32 NoExecute;
+ __u32 pad;
};
struct kfd_hsa_memory_exception_data {
struct kfd_memory_exception_failure failure;
- uint64_t va;
- uint32_t gpu_id;
- uint32_t pad;
+ __u64 va;
+ __u32 gpu_id;
+ __u32 pad;
};
struct kfd_event_data {
union {
struct kfd_hsa_memory_exception_data memory_exception_data;
};
- uint64_t kfd_event_data_ext;
- uint32_t event_id;
- uint32_t pad;
+ __u64 kfd_event_data_ext;
+ __u32 event_id;
+ __u32 pad;
};
struct kfd_ioctl_wait_events_args {
- uint64_t events_ptr;
- uint32_t num_events;
- uint32_t wait_for_all;
- uint32_t timeout;
- uint32_t wait_result;
+ __u64 events_ptr;
+ __u32 num_events;
+ __u32 wait_for_all;
+ __u32 timeout;
+ __u32 wait_result;
+};
+struct kfd_ioctl_set_scratch_backing_va_args {
+ uint64_t va_addr;
+ uint32_t gpu_id;
+ uint32_t pad;
+};
+struct kfd_ioctl_get_tile_config_args {
+ uint64_t tile_config_ptr;
+ uint64_t macro_tile_config_ptr;
+ uint32_t num_tile_configs;
+ uint32_t num_macro_tile_configs;
+ uint32_t gpu_id;
+ uint32_t gb_addr_config;
+ uint32_t num_banks;
+ uint32_t num_ranks;
};
#define AMDKFD_IOCTL_BASE 'K'
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
@@ -195,6 +210,8 @@
#define AMDKFD_IOC_DBG_UNREGISTER AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args)
#define AMDKFD_IOC_DBG_ADDRESS_WATCH AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args)
#define AMDKFD_IOC_DBG_WAVE_CONTROL AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args)
+#define AMDKFD_IOC_SET_SCRATCH_BACKING_VA AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args)
+#define AMDKFD_IOC_GET_TILE_CONFIG AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args)
#define AMDKFD_COMMAND_START 0x01
-#define AMDKFD_COMMAND_END 0x11
+#define AMDKFD_COMMAND_END 0x13
#endif
diff --git a/libc/kernel/uapi/linux/kvm.h b/libc/kernel/uapi/linux/kvm.h
index f61a08b..6bd4701 100644
--- a/libc/kernel/uapi/linux/kvm.h
+++ b/libc/kernel/uapi/linux/kvm.h
@@ -123,6 +123,17 @@
__u32 flags;
__u32 reserved[9];
};
+#define KVM_S390_CMMA_PEEK (1 << 0)
+struct kvm_s390_cmma_log {
+ __u64 start_gfn;
+ __u32 count;
+ __u32 flags;
+ union {
+ __u64 remaining;
+ __u64 mask;
+ };
+ __u64 values;
+};
struct kvm_hyperv_exit {
#define KVM_EXIT_HYPERV_SYNIC 1
#define KVM_EXIT_HYPERV_HCALL 2
@@ -526,7 +537,8 @@
struct kvm_ppc_smmu_info {
__u64 flags;
__u32 slb_size;
- __u32 pad;
+ __u16 data_keys;
+ __u16 instr_keys;
struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
};
struct kvm_ppc_resize_hpt {
@@ -711,6 +723,11 @@
#define KVM_CAP_SPAPR_TCE_VFIO 142
#define KVM_CAP_X86_GUEST_MWAIT 143
#define KVM_CAP_ARM_USER_IRQ 144
+#define KVM_CAP_S390_CMMA_MIGRATION 145
+#define KVM_CAP_PPC_FWNMI 146
+#define KVM_CAP_PPC_SMT_POSSIBLE 147
+#define KVM_CAP_HYPERV_SYNIC2 148
+#define KVM_CAP_HYPERV_VP_INDEX 149
#ifdef KVM_CAP_IRQ_ROUTING
struct kvm_irq_routing_irqchip {
__u32 irqchip;
@@ -1009,6 +1026,8 @@
#define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state)
#define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state)
#define KVM_SMI _IO(KVMIO, 0xb7)
+#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log)
+#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2)
diff --git a/libc/kernel/uapi/linux/limits.h b/libc/kernel/uapi/linux/limits.h
index 41108f9..ad0e33e 100644
--- a/libc/kernel/uapi/linux/limits.h
+++ b/libc/kernel/uapi/linux/limits.h
@@ -20,7 +20,7 @@
#define _LINUX_LIMITS_H
#define NR_OPEN 1024
#define NGROUPS_MAX 65536
-#define _KERNEL_ARG_MAX 131072
+#define ARG_MAX 131072
#define LINK_MAX 127
#define MAX_CANON 255
#define MAX_INPUT 255
diff --git a/libc/kernel/uapi/linux/loop.h b/libc/kernel/uapi/linux/loop.h
index ff3482f..d5a23b5 100644
--- a/libc/kernel/uapi/linux/loop.h
+++ b/libc/kernel/uapi/linux/loop.h
@@ -77,6 +77,7 @@
#define LOOP_CHANGE_FD 0x4C06
#define LOOP_SET_CAPACITY 0x4C07
#define LOOP_SET_DIRECT_IO 0x4C08
+#define LOOP_SET_BLOCK_SIZE 0x4C09
#define LOOP_CTL_ADD 0x4C80
#define LOOP_CTL_REMOVE 0x4C81
#define LOOP_CTL_GET_FREE 0x4C82
diff --git a/libc/kernel/uapi/linux/lwtunnel.h b/libc/kernel/uapi/linux/lwtunnel.h
index c88d866..05cc4fd 100644
--- a/libc/kernel/uapi/linux/lwtunnel.h
+++ b/libc/kernel/uapi/linux/lwtunnel.h
@@ -27,6 +27,7 @@
LWTUNNEL_ENCAP_IP6,
LWTUNNEL_ENCAP_SEG6,
LWTUNNEL_ENCAP_BPF,
+ LWTUNNEL_ENCAP_SEG6_LOCAL,
__LWTUNNEL_ENCAP_MAX,
};
#define LWTUNNEL_ENCAP_MAX (__LWTUNNEL_ENCAP_MAX - 1)
diff --git a/libc/kernel/uapi/linux/magic.h b/libc/kernel/uapi/linux/magic.h
index a9dac5d..6e0ddf7 100644
--- a/libc/kernel/uapi/linux/magic.h
+++ b/libc/kernel/uapi/linux/magic.h
@@ -57,6 +57,7 @@
#define MSDOS_SUPER_MAGIC 0x4d44
#define NCP_SUPER_MAGIC 0x564c
#define NFS_SUPER_MAGIC 0x6969
+#define OCFS2_SUPER_MAGIC 0x7461636f
#define OPENPROM_SUPER_MAGIC 0x9fa1
#define QNX4_SUPER_MAGIC 0x002f
#define QNX6_SUPER_MAGIC 0x68191122
@@ -86,6 +87,7 @@
#define BTRFS_TEST_MAGIC 0x73727279
#define NSFS_MAGIC 0x6e736673
#define BPF_FS_MAGIC 0xcafe4a11
+#define AAFS_MAGIC 0x5a3c69f0
#define UDF_SUPER_MAGIC 0x15013346
#define BALLOON_KVM_MAGIC 0x13661366
#define ZSMALLOC_MAGIC 0x58295829
diff --git a/libc/kernel/uapi/linux/wil6210_uapi.h b/libc/kernel/uapi/linux/max2175.h
similarity index 62%
copy from libc/kernel/uapi/linux/wil6210_uapi.h
copy to libc/kernel/uapi/linux/max2175.h
index e68b6c8..e6998e1 100644
--- a/libc/kernel/uapi/linux/wil6210_uapi.h
+++ b/libc/kernel/uapi/linux/max2175.h
@@ -16,30 +16,10 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __WIL6210_UAPI_H__
-#define __WIL6210_UAPI_H__
-#define __user
-#include <linux/sockios.h>
-#define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
-#define WIL_IOCTL_MEMIO_BLOCK (SIOCDEVPRIVATE + 3)
-enum wil_memio_op {
- wil_mmio_read = 0,
- wil_mmio_write = 1,
- wil_mmio_op_mask = 0xff,
- wil_mmio_addr_linker = 0 << 8,
- wil_mmio_addr_ahb = 1 << 8,
- wil_mmio_addr_bar = 2 << 8,
- wil_mmio_addr_mask = 0xff00,
-};
-struct wil_memio {
- uint32_t op;
- uint32_t addr;
- uint32_t val;
-};
-struct wil_memio_block {
- uint32_t op;
- uint32_t addr;
- uint32_t size;
- void __user * block;
-};
+#ifndef __UAPI_MAX2175_H_
+#define __UAPI_MAX2175_H_
+#include <linux/v4l2-controls.h>
+#define V4L2_CID_MAX2175_I2S_ENABLE (V4L2_CID_USER_MAX217X_BASE + 0x01)
+#define V4L2_CID_MAX2175_HSLS (V4L2_CID_USER_MAX217X_BASE + 0x02)
+#define V4L2_CID_MAX2175_RX_MODE (V4L2_CID_USER_MAX217X_BASE + 0x03)
#endif
diff --git a/libc/kernel/uapi/linux/media.h b/libc/kernel/uapi/linux/media.h
index 690d9b2a..b24d616 100644
--- a/libc/kernel/uapi/linux/media.h
+++ b/libc/kernel/uapi/linux/media.h
@@ -22,7 +22,6 @@
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/version.h>
-#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
struct media_device_info {
char driver[16];
char model[32];
@@ -56,6 +55,8 @@
#define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004)
#define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005)
#define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006)
+#define MEDIA_ENT_F_VID_MUX (MEDIA_ENT_F_BASE + 0x5001)
+#define MEDIA_ENT_F_VID_IF_BRIDGE (MEDIA_ENT_F_BASE + 0x5002)
#define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1)
#define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1)
#define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2)
@@ -80,6 +81,7 @@
#define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS
#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER
#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER
+#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
#define MEDIA_ENT_FL_DEFAULT (1 << 0)
#define MEDIA_ENT_FL_CONNECTOR (1 << 1)
struct media_entity_desc {
diff --git a/libc/kernel/uapi/linux/membarrier.h b/libc/kernel/uapi/linux/membarrier.h
index e9edbaa..2f5ea7d 100644
--- a/libc/kernel/uapi/linux/membarrier.h
+++ b/libc/kernel/uapi/linux/membarrier.h
@@ -21,5 +21,7 @@
enum membarrier_cmd {
MEMBARRIER_CMD_QUERY = 0,
MEMBARRIER_CMD_SHARED = (1 << 0),
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
};
#endif
diff --git a/libc/kernel/uapi/linux/memfd.h b/libc/kernel/uapi/linux/memfd.h
index d3d08a1..e3e5cd5 100644
--- a/libc/kernel/uapi/linux/memfd.h
+++ b/libc/kernel/uapi/linux/memfd.h
@@ -18,6 +18,20 @@
****************************************************************************/
#ifndef _UAPI_LINUX_MEMFD_H
#define _UAPI_LINUX_MEMFD_H
+#include <asm-generic/hugetlb_encode.h>
#define MFD_CLOEXEC 0x0001U
#define MFD_ALLOW_SEALING 0x0002U
+#define MFD_HUGETLB 0x0004U
+#define MFD_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define MFD_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define MFD_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define MFD_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define MFD_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define MFD_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define MFD_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define MFD_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define MFD_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define MFD_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define MFD_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define MFD_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
#endif
diff --git a/libc/kernel/uapi/linux/mempolicy.h b/libc/kernel/uapi/linux/mempolicy.h
index 081f9d6..6f721f6 100644
--- a/libc/kernel/uapi/linux/mempolicy.h
+++ b/libc/kernel/uapi/linux/mempolicy.h
@@ -27,12 +27,6 @@
MPOL_LOCAL,
MPOL_MAX,
};
-enum mpol_rebind_step {
- MPOL_REBIND_ONCE,
- MPOL_REBIND_STEP1,
- MPOL_REBIND_STEP2,
- MPOL_REBIND_NSTEP,
-};
#define MPOL_F_STATIC_NODES (1 << 15)
#define MPOL_F_RELATIVE_NODES (1 << 14)
#define MPOL_MODE_FLAGS (MPOL_F_STATIC_NODES | MPOL_F_RELATIVE_NODES)
@@ -47,7 +41,6 @@
#define MPOL_MF_VALID (MPOL_MF_STRICT | MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)
#define MPOL_F_SHARED (1 << 0)
#define MPOL_F_LOCAL (1 << 1)
-#define MPOL_F_REBINDING (1 << 2)
#define MPOL_F_MOF (1 << 3)
#define MPOL_F_MORON (1 << 4)
#endif
diff --git a/libc/kernel/uapi/linux/mman.h b/libc/kernel/uapi/linux/mman.h
index c5b3130..b0ce77e 100644
--- a/libc/kernel/uapi/linux/mman.h
+++ b/libc/kernel/uapi/linux/mman.h
@@ -19,9 +19,22 @@
#ifndef _UAPI_LINUX_MMAN_H
#define _UAPI_LINUX_MMAN_H
#include <asm/mman.h>
+#include <asm-generic/hugetlb_encode.h>
#define MREMAP_MAYMOVE 1
#define MREMAP_FIXED 2
#define OVERCOMMIT_GUESS 0
#define OVERCOMMIT_ALWAYS 1
#define OVERCOMMIT_NEVER 2
+#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
#endif
diff --git a/libc/kernel/uapi/linux/mroute.h b/libc/kernel/uapi/linux/mroute.h
index 9f4c937..d962f8b 100644
--- a/libc/kernel/uapi/linux/mroute.h
+++ b/libc/kernel/uapi/linux/mroute.h
@@ -95,6 +95,48 @@
unsigned char unused3;
struct in_addr im_src, im_dst;
};
+enum {
+ IPMRA_TABLE_UNSPEC,
+ IPMRA_TABLE_ID,
+ IPMRA_TABLE_CACHE_RES_QUEUE_LEN,
+ IPMRA_TABLE_MROUTE_REG_VIF_NUM,
+ IPMRA_TABLE_MROUTE_DO_ASSERT,
+ IPMRA_TABLE_MROUTE_DO_PIM,
+ IPMRA_TABLE_VIFS,
+ __IPMRA_TABLE_MAX
+};
+#define IPMRA_TABLE_MAX (__IPMRA_TABLE_MAX - 1)
+enum {
+ IPMRA_VIF_UNSPEC,
+ IPMRA_VIF,
+ __IPMRA_VIF_MAX
+};
+#define IPMRA_VIF_MAX (__IPMRA_VIF_MAX - 1)
+enum {
+ IPMRA_VIFA_UNSPEC,
+ IPMRA_VIFA_IFINDEX,
+ IPMRA_VIFA_VIF_ID,
+ IPMRA_VIFA_FLAGS,
+ IPMRA_VIFA_BYTES_IN,
+ IPMRA_VIFA_BYTES_OUT,
+ IPMRA_VIFA_PACKETS_IN,
+ IPMRA_VIFA_PACKETS_OUT,
+ IPMRA_VIFA_LOCAL_ADDR,
+ IPMRA_VIFA_REMOTE_ADDR,
+ IPMRA_VIFA_PAD,
+ __IPMRA_VIFA_MAX
+};
+#define IPMRA_VIFA_MAX (__IPMRA_VIFA_MAX - 1)
+enum {
+ IPMRA_CREPORT_UNSPEC,
+ IPMRA_CREPORT_MSGTYPE,
+ IPMRA_CREPORT_VIF_ID,
+ IPMRA_CREPORT_SRC_ADDR,
+ IPMRA_CREPORT_DST_ADDR,
+ IPMRA_CREPORT_PKT,
+ __IPMRA_CREPORT_MAX
+};
+#define IPMRA_CREPORT_MAX (__IPMRA_CREPORT_MAX - 1)
#define MFC_ASSERT_THRESH (3 * HZ)
#define IGMPMSG_NOCACHE 1
#define IGMPMSG_WRONGVIF 2
diff --git a/libc/kernel/uapi/linux/mroute6.h b/libc/kernel/uapi/linux/mroute6.h
index d9c86bf..ccb38d9 100644
--- a/libc/kernel/uapi/linux/mroute6.h
+++ b/libc/kernel/uapi/linux/mroute6.h
@@ -94,4 +94,14 @@
__u32 im6_pad;
struct in6_addr im6_src, im6_dst;
};
+enum {
+ IP6MRA_CREPORT_UNSPEC,
+ IP6MRA_CREPORT_MSGTYPE,
+ IP6MRA_CREPORT_MIF_ID,
+ IP6MRA_CREPORT_SRC_ADDR,
+ IP6MRA_CREPORT_DST_ADDR,
+ IP6MRA_CREPORT_PKT,
+ __IP6MRA_CREPORT_MAX
+};
+#define IP6MRA_CREPORT_MAX (__IP6MRA_CREPORT_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/nbd.h b/libc/kernel/uapi/linux/nbd.h
index 50079fa..749c38a 100644
--- a/libc/kernel/uapi/linux/nbd.h
+++ b/libc/kernel/uapi/linux/nbd.h
@@ -40,8 +40,10 @@
#define NBD_FLAG_HAS_FLAGS (1 << 0)
#define NBD_FLAG_READ_ONLY (1 << 1)
#define NBD_FLAG_SEND_FLUSH (1 << 2)
+#define NBD_FLAG_SEND_FUA (1 << 3)
#define NBD_FLAG_SEND_TRIM (1 << 5)
#define NBD_FLAG_CAN_MULTI_CONN (1 << 8)
+#define NBD_CMD_FLAG_FUA (1 << 16)
#define NBD_CFLAG_DESTROY_ON_DISCONNECT (1 << 0)
#define NBD_REQUEST_MAGIC 0x25609513
#define NBD_REPLY_MAGIC 0x67446698
diff --git a/libc/kernel/uapi/linux/ndctl.h b/libc/kernel/uapi/linux/ndctl.h
index cfe5c9c..44c9ee0 100644
--- a/libc/kernel/uapi/linux/ndctl.h
+++ b/libc/kernel/uapi/linux/ndctl.h
@@ -98,7 +98,8 @@
__u32 status;
__u32 max_ars_out;
__u32 clear_err_unit;
- __u32 reserved;
+ __u16 flags;
+ __u16 reserved;
} __packed;
struct nd_cmd_ars_start {
__u64 address;
@@ -153,6 +154,7 @@
enum {
ND_ARS_VOLATILE = 1,
ND_ARS_PERSISTENT = 2,
+ ND_ARS_RETURN_PREV_DATA = 1 << 1,
ND_CONFIG_LOCKED = 1,
};
#define ND_IOCTL 'N'
diff --git a/libc/kernel/uapi/linux/neighbour.h b/libc/kernel/uapi/linux/neighbour.h
index 1a322de..cf32a12 100644
--- a/libc/kernel/uapi/linux/neighbour.h
+++ b/libc/kernel/uapi/linux/neighbour.h
@@ -50,6 +50,7 @@
#define NTF_MASTER 0x04
#define NTF_PROXY 0x08
#define NTF_EXT_LEARNED 0x10
+#define NTF_OFFLOADED 0x20
#define NTF_ROUTER 0x80
#define NUD_INCOMPLETE 0x01
#define NUD_REACHABLE 0x02
diff --git a/libc/kernel/uapi/linux/net_tstamp.h b/libc/kernel/uapi/linux/net_tstamp.h
index 9a2373e..49d4c2c 100644
--- a/libc/kernel/uapi/linux/net_tstamp.h
+++ b/libc/kernel/uapi/linux/net_tstamp.h
@@ -18,6 +18,7 @@
****************************************************************************/
#ifndef _NET_TIMESTAMPING_H
#define _NET_TIMESTAMPING_H
+#include <linux/types.h>
#include <linux/socket.h>
enum {
SOF_TIMESTAMPING_TX_HARDWARE = (1 << 0),
@@ -33,7 +34,9 @@
SOF_TIMESTAMPING_OPT_CMSG = (1 << 10),
SOF_TIMESTAMPING_OPT_TSONLY = (1 << 11),
SOF_TIMESTAMPING_OPT_STATS = (1 << 12),
- SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_STATS,
+ SOF_TIMESTAMPING_OPT_PKTINFO = (1 << 13),
+ SOF_TIMESTAMPING_OPT_TX_SWHW = (1 << 14),
+ SOF_TIMESTAMPING_LAST = SOF_TIMESTAMPING_OPT_TX_SWHW,
SOF_TIMESTAMPING_MASK = (SOF_TIMESTAMPING_LAST - 1) | SOF_TIMESTAMPING_LAST
};
#define SOF_TIMESTAMPING_TX_RECORD_MASK (SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE | SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_ACK)
@@ -63,5 +66,11 @@
HWTSTAMP_FILTER_PTP_V2_EVENT,
HWTSTAMP_FILTER_PTP_V2_SYNC,
HWTSTAMP_FILTER_PTP_V2_DELAY_REQ,
+ HWTSTAMP_FILTER_NTP_ALL,
+};
+struct scm_ts_pktinfo {
+ __u32 if_index;
+ __u32 pkt_length;
+ __u32 reserved[2];
};
#endif
diff --git a/libc/kernel/uapi/linux/netfilter/nf_tables.h b/libc/kernel/uapi/linux/netfilter/nf_tables.h
index c090f94..169fb33 100644
--- a/libc/kernel/uapi/linux/netfilter/nf_tables.h
+++ b/libc/kernel/uapi/linux/netfilter/nf_tables.h
@@ -18,10 +18,11 @@
****************************************************************************/
#ifndef _LINUX_NF_TABLES_H
#define _LINUX_NF_TABLES_H
-#define NFT_TABLE_MAXNAMELEN 32
-#define NFT_CHAIN_MAXNAMELEN 32
-#define NFT_SET_MAXNAMELEN 32
-#define NFT_OBJ_MAXNAMELEN 32
+#define NFT_NAME_MAXLEN 256
+#define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN
+#define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN
#define NFT_USERDATA_MAXLEN 256
enum nft_registers {
NFT_REG_VERDICT,
@@ -374,6 +375,7 @@
NFTA_EXTHDR_LEN,
NFTA_EXTHDR_FLAGS,
NFTA_EXTHDR_OP,
+ NFTA_EXTHDR_SREG,
__NFTA_EXTHDR_MAX
};
#define NFTA_EXTHDR_MAX (__NFTA_EXTHDR_MAX - 1)
@@ -408,6 +410,7 @@
NFT_RT_CLASSID,
NFT_RT_NEXTHOP4,
NFT_RT_NEXTHOP6,
+ NFT_RT_TCPMSS,
};
enum nft_hash_types {
NFT_HASH_JENKINS,
@@ -610,6 +613,8 @@
enum nft_gen_attributes {
NFTA_GEN_UNSPEC,
NFTA_GEN_ID,
+ NFTA_GEN_PROC_PID,
+ NFTA_GEN_PROC_NAME,
__NFTA_GEN_MAX
};
#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
@@ -649,7 +654,8 @@
#define NFT_OBJECT_COUNTER 1
#define NFT_OBJECT_QUOTA 2
#define NFT_OBJECT_CT_HELPER 3
-#define __NFT_OBJECT_MAX 4
+#define NFT_OBJECT_LIMIT 4
+#define __NFT_OBJECT_MAX 5
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
enum nft_object_attributes {
NFTA_OBJ_UNSPEC,
diff --git a/libc/kernel/uapi/linux/netfilter/xt_bpf.h b/libc/kernel/uapi/linux/netfilter/xt_bpf.h
index d9a54f9..043af45 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_bpf.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_bpf.h
@@ -34,6 +34,7 @@
XT_BPF_MODE_FD_PINNED,
XT_BPF_MODE_FD_ELF,
};
+#define XT_BPF_MODE_PATH_PINNED XT_BPF_MODE_FD_PINNED
struct xt_bpf_info_v1 {
__u16 mode;
__u16 bpf_program_num_elem;
diff --git a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
index c9d62f3..572c85d 100644
--- a/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
+++ b/libc/kernel/uapi/linux/netfilter/xt_hashlimit.h
@@ -32,6 +32,7 @@
XT_HASHLIMIT_HASH_SPT = 1 << 3,
XT_HASHLIMIT_INVERT = 1 << 4,
XT_HASHLIMIT_BYTES = 1 << 5,
+ XT_HASHLIMIT_RATE_MATCH = 1 << 6,
};
struct hashlimit_cfg {
__u32 mode;
@@ -71,6 +72,17 @@
__u32 expire;
__u8 srcmask, dstmask;
};
+struct hashlimit_cfg3 {
+ __u64 avg;
+ __u64 burst;
+ __u32 mode;
+ __u32 size;
+ __u32 max;
+ __u32 gc_interval;
+ __u32 expire;
+ __u32 interval;
+ __u8 srcmask, dstmask;
+};
struct xt_hashlimit_mtinfo1 {
char name[IFNAMSIZ];
struct hashlimit_cfg1 cfg;
@@ -81,4 +93,9 @@
struct hashlimit_cfg2 cfg;
struct xt_hashlimit_htable * hinfo __attribute__((aligned(8)));
};
+struct xt_hashlimit_mtinfo3 {
+ char name[NAME_MAX];
+ struct hashlimit_cfg3 cfg;
+ struct xt_hashlimit_htable * hinfo __attribute__((aligned(8)));
+};
#endif
diff --git a/libc/kernel/uapi/linux/netlink.h b/libc/kernel/uapi/linux/netlink.h
index 4eb428a..4f35c02 100644
--- a/libc/kernel/uapi/linux/netlink.h
+++ b/libc/kernel/uapi/linux/netlink.h
@@ -72,6 +72,7 @@
#define NLM_F_EXCL 0x200
#define NLM_F_CREATE 0x400
#define NLM_F_APPEND 0x800
+#define NLM_F_NONREC 0x100
#define NLM_F_CAPPED 0x100
#define NLM_F_ACK_TLVS 0x200
#define NLMSG_ALIGNTO 4U
@@ -153,4 +154,8 @@
#define NLA_ALIGNTO 4
#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
+struct nla_bitfield32 {
+ __u32 value;
+ __u32 selector;
+};
#endif
diff --git a/libc/kernel/uapi/linux/nl80211.h b/libc/kernel/uapi/linux/nl80211.h
index 103b9da..bb9a835 100644
--- a/libc/kernel/uapi/linux/nl80211.h
+++ b/libc/kernel/uapi/linux/nl80211.h
@@ -156,6 +156,8 @@
NL80211_CMD_NAN_MATCH,
NL80211_CMD_SET_MULTICAST_TO_UNICAST,
NL80211_CMD_UPDATE_CONNECT_PARAMS,
+ NL80211_CMD_SET_PMK,
+ NL80211_CMD_DEL_PMK,
__NL80211_CMD_AFTER_LAST,
NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1
};
@@ -429,6 +431,9 @@
NL80211_ATTR_PMK,
NL80211_ATTR_SCHED_SCAN_MULTI,
NL80211_ATTR_SCHED_SCAN_MAX_REQS,
+ NL80211_ATTR_WANT_1X_4WAY_HS,
+ NL80211_ATTR_PMKR0_NAME,
+ NL80211_ATTR_PORT_AUTHORIZED,
__NL80211_ATTR_AFTER_LAST,
NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST,
NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
@@ -1187,6 +1192,8 @@
NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI,
NL80211_EXT_FEATURE_CQM_RSSI_LIST,
NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
+ NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
NUM_NL80211_EXT_FEATURES,
MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1
};
diff --git a/libc/kernel/uapi/linux/pci_regs.h b/libc/kernel/uapi/linux/pci_regs.h
index baa9421..c7f8381 100644
--- a/libc/kernel/uapi/linux/pci_regs.h
+++ b/libc/kernel/uapi/linux/pci_regs.h
@@ -424,10 +424,12 @@
#define PCI_EXP_DEVSTA_URD 0x0008
#define PCI_EXP_DEVSTA_AUXPD 0x0010
#define PCI_EXP_DEVSTA_TRPND 0x0020
+#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12
#define PCI_EXP_LNKCAP 12
#define PCI_EXP_LNKCAP_SLS 0x0000000f
#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001
#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002
+#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003
#define PCI_EXP_LNKCAP_MLW 0x000003f0
#define PCI_EXP_LNKCAP_ASPMS 0x00000c00
#define PCI_EXP_LNKCAP_L0SEL 0x00007000
@@ -541,7 +543,7 @@
#define PCI_EXP_DEVCTL2_OBFF_MSGB_EN 0x4000
#define PCI_EXP_DEVCTL2_OBFF_WAKE_EN 0x6000
#define PCI_EXP_DEVSTA2 42
-#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 44
+#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 44
#define PCI_EXP_LNKCAP2 44
#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002
#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004
@@ -549,6 +551,7 @@
#define PCI_EXP_LNKCAP2_CROSSLINK 0x00000100
#define PCI_EXP_LNKCTL2 48
#define PCI_EXP_LNKSTA2 50
+#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 52
#define PCI_EXP_SLTCAP2 52
#define PCI_EXP_SLTCTL2 56
#define PCI_EXP_SLTSTA2 58
@@ -814,6 +817,7 @@
#define PCI_EXP_DPC_CAP_RP_EXT 0x20
#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40
#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00
#define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000
#define PCI_EXP_DPC_CTL 6
#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02
@@ -823,6 +827,14 @@
#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08
#define PCI_EXP_DPC_RP_BUSY 0x10
#define PCI_EXP_DPC_SOURCE_ID 10
+#define PCI_EXP_DPC_RP_PIO_STATUS 0x0C
+#define PCI_EXP_DPC_RP_PIO_MASK 0x10
+#define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14
+#define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18
+#define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C
+#define PCI_EXP_DPC_RP_PIO_HEADER_LOG 0x20
+#define PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG 0x30
+#define PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG 0x34
#define PCI_PTM_CAP 0x04
#define PCI_PTM_CAP_REQ 0x00000001
#define PCI_PTM_CAP_ROOT 0x00000004
diff --git a/libc/kernel/uapi/linux/perf_event.h b/libc/kernel/uapi/linux/perf_event.h
index 8adad9c..326827e 100644
--- a/libc/kernel/uapi/linux/perf_event.h
+++ b/libc/kernel/uapi/linux/perf_event.h
@@ -98,7 +98,8 @@
PERF_SAMPLE_IDENTIFIER = 1U << 16,
PERF_SAMPLE_TRANSACTION = 1U << 17,
PERF_SAMPLE_REGS_INTR = 1U << 18,
- PERF_SAMPLE_MAX = 1U << 19,
+ PERF_SAMPLE_PHYS_ADDR = 1U << 19,
+ PERF_SAMPLE_MAX = 1U << 20,
};
enum perf_branch_sample_type_shift {
PERF_SAMPLE_BRANCH_USER_SHIFT = 0,
@@ -117,6 +118,7 @@
PERF_SAMPLE_BRANCH_CALL_SHIFT = 13,
PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14,
PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15,
+ PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16,
PERF_SAMPLE_BRANCH_MAX_SHIFT
};
enum perf_branch_sample_type {
@@ -136,8 +138,23 @@
PERF_SAMPLE_BRANCH_CALL = 1U << PERF_SAMPLE_BRANCH_CALL_SHIFT,
PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT,
PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT,
+ PERF_SAMPLE_BRANCH_TYPE_SAVE = 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT,
PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
};
+enum {
+ PERF_BR_UNKNOWN = 0,
+ PERF_BR_COND = 1,
+ PERF_BR_UNCOND = 2,
+ PERF_BR_IND = 3,
+ PERF_BR_CALL = 4,
+ PERF_BR_IND_CALL = 5,
+ PERF_BR_RET = 6,
+ PERF_BR_SYSCALL = 7,
+ PERF_BR_SYSRET = 8,
+ PERF_BR_COND_CALL = 9,
+ PERF_BR_COND_RET = 10,
+ PERF_BR_MAX,
+};
#define PERF_SAMPLE_BRANCH_PLM_ALL (PERF_SAMPLE_BRANCH_USER | PERF_SAMPLE_BRANCH_KERNEL | PERF_SAMPLE_BRANCH_HV)
enum perf_sample_regs_abi {
PERF_SAMPLE_REGS_ABI_NONE = 0,
@@ -320,14 +337,14 @@
union perf_mem_data_src {
__u64 val;
struct {
- __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_rsvd : 31;
+ __u64 mem_op : 5, mem_lvl : 14, mem_snoop : 5, mem_lock : 2, mem_dtlb : 7, mem_lvl_num : 4, mem_remote : 1, mem_snoopx : 2, mem_rsvd : 24;
};
};
#elif defined(__BIG_ENDIAN_BITFIELD)
union perf_mem_data_src {
__u64 val;
struct {
- __u64 mem_rsvd : 31, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
+ __u64 mem_rsvd : 24, mem_snoopx : 2, mem_remote : 1, mem_lvl_num : 4, mem_dtlb : 7, mem_lock : 2, mem_snoop : 5, mem_lvl : 14, mem_op : 5;
};
};
#else
@@ -354,12 +371,26 @@
#define PERF_MEM_LVL_IO 0x1000
#define PERF_MEM_LVL_UNC 0x2000
#define PERF_MEM_LVL_SHIFT 5
+#define PERF_MEM_REMOTE_REMOTE 0x01
+#define PERF_MEM_REMOTE_SHIFT 37
+#define PERF_MEM_LVLNUM_L1 0x01
+#define PERF_MEM_LVLNUM_L2 0x02
+#define PERF_MEM_LVLNUM_L3 0x03
+#define PERF_MEM_LVLNUM_L4 0x04
+#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b
+#define PERF_MEM_LVLNUM_LFB 0x0c
+#define PERF_MEM_LVLNUM_RAM 0x0d
+#define PERF_MEM_LVLNUM_PMEM 0x0e
+#define PERF_MEM_LVLNUM_NA 0x0f
+#define PERF_MEM_LVLNUM_SHIFT 33
#define PERF_MEM_SNOOP_NA 0x01
#define PERF_MEM_SNOOP_NONE 0x02
#define PERF_MEM_SNOOP_HIT 0x04
#define PERF_MEM_SNOOP_MISS 0x08
#define PERF_MEM_SNOOP_HITM 0x10
#define PERF_MEM_SNOOP_SHIFT 19
+#define PERF_MEM_SNOOPX_FWD 0x01
+#define PERF_MEM_SNOOPX_SHIFT 37
#define PERF_MEM_LOCK_NA 0x01
#define PERF_MEM_LOCK_LOCKED 0x02
#define PERF_MEM_LOCK_SHIFT 24
@@ -375,6 +406,6 @@
struct perf_branch_entry {
__u64 from;
__u64 to;
- __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, reserved : 44;
+ __u64 mispred : 1, predicted : 1, in_tx : 1, abort : 1, cycles : 16, type : 4, reserved : 40;
};
#endif
diff --git a/libc/kernel/uapi/linux/pkt_cls.h b/libc/kernel/uapi/linux/pkt_cls.h
index af251c0..4bac8f9 100644
--- a/libc/kernel/uapi/linux/pkt_cls.h
+++ b/libc/kernel/uapi/linux/pkt_cls.h
@@ -49,11 +49,13 @@
#define TC_ACT_QUEUED 5
#define TC_ACT_REPEAT 6
#define TC_ACT_REDIRECT 7
+#define TC_ACT_TRAP 8
#define __TC_ACT_EXT_SHIFT 28
#define __TC_ACT_EXT(local) ((local) << __TC_ACT_EXT_SHIFT)
#define TC_ACT_EXT_VAL_MASK ((1 << __TC_ACT_EXT_SHIFT) - 1)
#define TC_ACT_EXT_CMP(combined,opcode) (((combined) & (~TC_ACT_EXT_VAL_MASK)) == opcode)
#define TC_ACT_JUMP __TC_ACT_EXT(1)
+#define TC_ACT_GOTO_CHAIN __TC_ACT_EXT(2)
enum {
TCA_ID_UNSPEC = 0,
TCA_ID_POLICE = 1,
@@ -291,6 +293,7 @@
TCA_BPF_FLAGS,
TCA_BPF_FLAGS_GEN,
TCA_BPF_TAG,
+ TCA_BPF_ID,
__TCA_BPF_MAX,
};
#define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
@@ -366,6 +369,12 @@
TCA_FLOWER_KEY_MPLS_BOS,
TCA_FLOWER_KEY_MPLS_TC,
TCA_FLOWER_KEY_MPLS_LABEL,
+ TCA_FLOWER_KEY_TCP_FLAGS,
+ TCA_FLOWER_KEY_TCP_FLAGS_MASK,
+ TCA_FLOWER_KEY_IP_TOS,
+ TCA_FLOWER_KEY_IP_TOS_MASK,
+ TCA_FLOWER_KEY_IP_TTL,
+ TCA_FLOWER_KEY_IP_TTL_MASK,
__TCA_FLOWER_MAX,
};
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
diff --git a/libc/kernel/uapi/linux/quota.h b/libc/kernel/uapi/linux/quota.h
index cc5ccbb..280b396 100644
--- a/libc/kernel/uapi/linux/quota.h
+++ b/libc/kernel/uapi/linux/quota.h
@@ -18,7 +18,6 @@
****************************************************************************/
#ifndef _UAPI_LINUX_QUOTA_
#define _UAPI_LINUX_QUOTA_
-#include <linux/errno.h>
#include <linux/types.h>
#define __DQUOT_VERSION__ "dquot_6.6.0"
#define MAXQUOTAS 3
diff --git a/libc/kernel/uapi/linux/raid/md_p.h b/libc/kernel/uapi/linux/raid/md_p.h
index ea54bdb..0bc6756 100644
--- a/libc/kernel/uapi/linux/raid/md_p.h
+++ b/libc/kernel/uapi/linux/raid/md_p.h
@@ -181,7 +181,8 @@
#define MD_FEATURE_CLUSTERED 256
#define MD_FEATURE_JOURNAL 512
#define MD_FEATURE_PPL 1024
-#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL | MD_FEATURE_PPL)
+#define MD_FEATURE_MULTIPLE_PPLS 2048
+#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET | MD_FEATURE_RECOVERY_OFFSET | MD_FEATURE_RESHAPE_ACTIVE | MD_FEATURE_BAD_BLOCKS | MD_FEATURE_REPLACEMENT | MD_FEATURE_RESHAPE_BACKWARDS | MD_FEATURE_NEW_OFFSET | MD_FEATURE_RECOVERY_BITMAP | MD_FEATURE_CLUSTERED | MD_FEATURE_JOURNAL | MD_FEATURE_PPL | MD_FEATURE_MULTIPLE_PPLS)
struct r5l_payload_header {
__le16 type;
__le16 flags;
diff --git a/libc/kernel/uapi/linux/rtnetlink.h b/libc/kernel/uapi/linux/rtnetlink.h
index d094068..c363e34 100644
--- a/libc/kernel/uapi/linux/rtnetlink.h
+++ b/libc/kernel/uapi/linux/rtnetlink.h
@@ -131,6 +131,8 @@
#define RTM_NEWSTATS RTM_NEWSTATS
RTM_GETSTATS = 94,
#define RTM_GETSTATS RTM_GETSTATS
+ RTM_NEWCACHEREPORT = 96,
+#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -204,6 +206,7 @@
#define RTM_F_EQUALIZE 0x400
#define RTM_F_PREFIX 0x800
#define RTM_F_LOOKUP_TABLE 0x1000
+#define RTM_F_FIB_MATCH 0x2000
enum rt_class_t {
RT_TABLE_UNSPEC = 0,
RT_TABLE_COMPAT = 252,
@@ -398,6 +401,7 @@
TCA_STAB,
TCA_PAD,
TCA_DUMP_INVISIBLE,
+ TCA_CHAIN,
__TCA_MAX
};
#define TCA_MAX (__TCA_MAX - 1)
@@ -493,6 +497,10 @@
#define RTNLGRP_NSID RTNLGRP_NSID
RTNLGRP_MPLS_NETCONF,
#define RTNLGRP_MPLS_NETCONF RTNLGRP_MPLS_NETCONF
+ RTNLGRP_IPV4_MROUTE_R,
+#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
+ RTNLGRP_IPV6_MROUTE_R,
+#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
@@ -501,10 +509,20 @@
unsigned char tca__pad1;
unsigned short tca__pad2;
};
+enum {
+ TCA_ROOT_UNSPEC,
+ TCA_ROOT_TAB,
+#define TCA_ACT_TAB TCA_ROOT_TAB
+#define TCAA_MAX TCA_ROOT_TAB
+ TCA_ROOT_FLAGS,
+ TCA_ROOT_COUNT,
+ TCA_ROOT_TIME_DELTA,
+ __TCA_ROOT_MAX,
+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
+};
#define TA_RTA(r) ((struct rtattr *) (((char *) (r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct tcamsg))
-#define TCA_ACT_TAB 1
-#define TCAA_MAX 1
+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
#define RTEXT_FILTER_VF (1 << 0)
#define RTEXT_FILTER_BRVLAN (1 << 1)
#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
diff --git a/libc/kernel/uapi/linux/rxrpc.h b/libc/kernel/uapi/linux/rxrpc.h
new file mode 100644
index 0000000..b8b7b04
--- /dev/null
+++ b/libc/kernel/uapi/linux/rxrpc.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_RXRPC_H
+#define _UAPI_LINUX_RXRPC_H
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+struct sockaddr_rxrpc {
+ sa_family_t srx_family;
+ u16 srx_service;
+ u16 transport_type;
+ u16 transport_len;
+ union {
+ sa_family_t family;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } transport;
+};
+#define RXRPC_SECURITY_KEY 1
+#define RXRPC_SECURITY_KEYRING 2
+#define RXRPC_EXCLUSIVE_CONNECTION 3
+#define RXRPC_MIN_SECURITY_LEVEL 4
+#define RXRPC_UPGRADEABLE_SERVICE 5
+#define RXRPC_SUPPORTED_CMSG 6
+enum rxrpc_cmsg_type {
+ RXRPC_USER_CALL_ID = 1,
+ RXRPC_ABORT = 2,
+ RXRPC_ACK = 3,
+ RXRPC_NET_ERROR = 5,
+ RXRPC_BUSY = 6,
+ RXRPC_LOCAL_ERROR = 7,
+ RXRPC_NEW_CALL = 8,
+ RXRPC_ACCEPT = 9,
+ RXRPC_EXCLUSIVE_CALL = 10,
+ RXRPC_UPGRADE_SERVICE = 11,
+ RXRPC_TX_LENGTH = 12,
+ RXRPC__SUPPORTED
+};
+#define RXRPC_SECURITY_PLAIN 0
+#define RXRPC_SECURITY_AUTH 1
+#define RXRPC_SECURITY_ENCRYPT 2
+#define RXRPC_SECURITY_NONE 0
+#define RXRPC_SECURITY_RXKAD 2
+#define RXRPC_SECURITY_RXGK 4
+#define RXRPC_SECURITY_RXK5 5
+#define RX_CALL_DEAD - 1
+#define RX_INVALID_OPERATION - 2
+#define RX_CALL_TIMEOUT - 3
+#define RX_EOF - 4
+#define RX_PROTOCOL_ERROR - 5
+#define RX_USER_ABORT - 6
+#define RX_ADDRINUSE - 7
+#define RX_DEBUGI_BADTYPE - 8
+#define RXGEN_CC_MARSHAL - 450
+#define RXGEN_CC_UNMARSHAL - 451
+#define RXGEN_SS_MARSHAL - 452
+#define RXGEN_SS_UNMARSHAL - 453
+#define RXGEN_DECODE - 454
+#define RXGEN_OPCODE - 455
+#define RXGEN_SS_XDRFREE - 456
+#define RXGEN_CC_XDRFREE - 457
+#define RXKADINCONSISTENCY 19270400
+#define RXKADPACKETSHORT 19270401
+#define RXKADLEVELFAIL 19270402
+#define RXKADTICKETLEN 19270403
+#define RXKADOUTOFSEQUENCE 19270404
+#define RXKADNOAUTH 19270405
+#define RXKADBADKEY 19270406
+#define RXKADBADTICKET 19270407
+#define RXKADUNKNOWNKEY 19270408
+#define RXKADEXPIRED 19270409
+#define RXKADSEALEDINCON 19270410
+#define RXKADDATALEN 19270411
+#define RXKADILLEGALLEVEL 19270412
+#endif
diff --git a/libc/kernel/uapi/linux/sched.h b/libc/kernel/uapi/linux/sched.h
index 8d149b8..9958fba 100644
--- a/libc/kernel/uapi/linux/sched.h
+++ b/libc/kernel/uapi/linux/sched.h
@@ -50,4 +50,5 @@
#define SCHED_DEADLINE 6
#define SCHED_RESET_ON_FORK 0x40000000
#define SCHED_FLAG_RESET_ON_FORK 0x01
+#define SCHED_FLAG_RECLAIM 0x02
#endif
diff --git a/libc/kernel/uapi/linux/sctp.h b/libc/kernel/uapi/linux/sctp.h
index a5cef43..9a55459 100644
--- a/libc/kernel/uapi/linux/sctp.h
+++ b/libc/kernel/uapi/linux/sctp.h
@@ -76,6 +76,7 @@
#define SCTP_RESET_STREAMS 119
#define SCTP_RESET_ASSOC 120
#define SCTP_ADD_STREAMS 121
+#define SCTP_SOCKOPT_PEELOFF_FLAGS 122
#define SCTP_PR_SCTP_NONE 0x0000
#define SCTP_PR_SCTP_TTL 0x0010
#define SCTP_PR_SCTP_RTX 0x0020
@@ -204,7 +205,7 @@
__u16 sre_type;
__u16 sre_flags;
__u32 sre_length;
- __u16 sre_error;
+ __be16 sre_error;
sctp_assoc_t sre_assoc_id;
__u8 sre_data[0];
};
@@ -525,6 +526,10 @@
sctp_assoc_t associd;
int sd;
} sctp_peeloff_arg_t;
+typedef struct {
+ sctp_peeloff_arg_t p_arg;
+ unsigned flags;
+} sctp_peeloff_flags_arg_t;
struct sctp_paddrthlds {
sctp_assoc_t spt_assoc_id;
struct sockaddr_storage spt_address;
diff --git a/libc/kernel/uapi/linux/seccomp.h b/libc/kernel/uapi/linux/seccomp.h
index db041a3..1fd53fc 100644
--- a/libc/kernel/uapi/linux/seccomp.h
+++ b/libc/kernel/uapi/linux/seccomp.h
@@ -25,12 +25,18 @@
#define SECCOMP_MODE_FILTER 2
#define SECCOMP_SET_MODE_STRICT 0
#define SECCOMP_SET_MODE_FILTER 1
+#define SECCOMP_GET_ACTION_AVAIL 2
#define SECCOMP_FILTER_FLAG_TSYNC 1
-#define SECCOMP_RET_KILL 0x00000000U
+#define SECCOMP_FILTER_FLAG_LOG 2
+#define SECCOMP_RET_KILL_PROCESS 0x80000000U
+#define SECCOMP_RET_KILL_THREAD 0x00000000U
+#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD
#define SECCOMP_RET_TRAP 0x00030000U
#define SECCOMP_RET_ERRNO 0x00050000U
#define SECCOMP_RET_TRACE 0x7ff00000U
+#define SECCOMP_RET_LOG 0x7ffc0000U
#define SECCOMP_RET_ALLOW 0x7fff0000U
+#define SECCOMP_RET_ACTION_FULL 0xffff0000U
#define SECCOMP_RET_ACTION 0x7fff0000U
#define SECCOMP_RET_DATA 0x0000ffffU
struct seccomp_data {
diff --git a/libc/kernel/uapi/linux/seg6_iptunnel.h b/libc/kernel/uapi/linux/seg6_iptunnel.h
index 747fa09..1c1ad83 100644
--- a/libc/kernel/uapi/linux/seg6_iptunnel.h
+++ b/libc/kernel/uapi/linux/seg6_iptunnel.h
@@ -33,5 +33,6 @@
enum {
SEG6_IPTUN_MODE_INLINE,
SEG6_IPTUN_MODE_ENCAP,
+ SEG6_IPTUN_MODE_L2ENCAP,
};
#endif
diff --git a/libc/kernel/uapi/linux/seg6_local.h b/libc/kernel/uapi/linux/seg6_local.h
new file mode 100644
index 0000000..7a10701
--- /dev/null
+++ b/libc/kernel/uapi/linux/seg6_local.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_SEG6_LOCAL_H
+#define _UAPI_LINUX_SEG6_LOCAL_H
+#include <linux/seg6.h>
+enum {
+ SEG6_LOCAL_UNSPEC,
+ SEG6_LOCAL_ACTION,
+ SEG6_LOCAL_SRH,
+ SEG6_LOCAL_TABLE,
+ SEG6_LOCAL_NH4,
+ SEG6_LOCAL_NH6,
+ SEG6_LOCAL_IIF,
+ SEG6_LOCAL_OIF,
+ __SEG6_LOCAL_MAX,
+};
+#define SEG6_LOCAL_MAX (__SEG6_LOCAL_MAX - 1)
+enum {
+ SEG6_LOCAL_ACTION_UNSPEC = 0,
+ SEG6_LOCAL_ACTION_END = 1,
+ SEG6_LOCAL_ACTION_END_X = 2,
+ SEG6_LOCAL_ACTION_END_T = 3,
+ SEG6_LOCAL_ACTION_END_DX2 = 4,
+ SEG6_LOCAL_ACTION_END_DX6 = 5,
+ SEG6_LOCAL_ACTION_END_DX4 = 6,
+ SEG6_LOCAL_ACTION_END_DT6 = 7,
+ SEG6_LOCAL_ACTION_END_DT4 = 8,
+ SEG6_LOCAL_ACTION_END_B6 = 9,
+ SEG6_LOCAL_ACTION_END_B6_ENCAP = 10,
+ SEG6_LOCAL_ACTION_END_BM = 11,
+ SEG6_LOCAL_ACTION_END_S = 12,
+ SEG6_LOCAL_ACTION_END_AS = 13,
+ SEG6_LOCAL_ACTION_END_AM = 14,
+ __SEG6_LOCAL_ACTION_MAX,
+};
+#define SEG6_LOCAL_ACTION_MAX (__SEG6_LOCAL_ACTION_MAX - 1)
+#endif
diff --git a/libc/kernel/uapi/linux/serial.h b/libc/kernel/uapi/linux/serial.h
index 219a2ea..79f11e3 100644
--- a/libc/kernel/uapi/linux/serial.h
+++ b/libc/kernel/uapi/linux/serial.h
@@ -95,6 +95,7 @@
#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)
__u32 delay_rts_before_send;
__u32 delay_rts_after_send;
__u32 padding[5];
diff --git a/libc/kernel/uapi/linux/serial_core.h b/libc/kernel/uapi/linux/serial_core.h
index af349c2..68d2dcb 100644
--- a/libc/kernel/uapi/linux/serial_core.h
+++ b/libc/kernel/uapi/linux/serial_core.h
@@ -50,16 +50,17 @@
#define PORT_ALTR_16550_F128 28
#define PORT_RT2880 29
#define PORT_16550A_FSL64 30
-#define PORT_DA830 31
-#define PORT_MAX_8250 31
#define PORT_PXA 31
#define PORT_AMBA 32
#define PORT_CLPS711X 33
#define PORT_SA1100 34
#define PORT_UART00 35
+#define PORT_OWL 36
#define PORT_21285 37
#define PORT_SUNZILOG 38
#define PORT_SUNSAB 39
+#define PORT_PCH_8LINE 44
+#define PORT_PCH_2LINE 45
#define PORT_DZ 46
#define PORT_ZS 47
#define PORT_MUX 48
@@ -109,7 +110,7 @@
#define PORT_ALTERA_UART 92
#define PORT_SCIFB 93
#define PORT_MAX310X 94
-#define PORT_MFD 95
+#define PORT_DA830 95
#define PORT_OMAP 96
#define PORT_VT8500 97
#define PORT_XUARTPS 98
@@ -131,4 +132,5 @@
#define PORT_MVEBU 114
#define PORT_PIC32 115
#define PORT_MPS2UART 116
+#define PORT_MTK_BTIF 117
#endif
diff --git a/libc/kernel/uapi/linux/shm.h b/libc/kernel/uapi/linux/shm.h
index ab319f2..a3071e7 100644
--- a/libc/kernel/uapi/linux/shm.h
+++ b/libc/kernel/uapi/linux/shm.h
@@ -20,6 +20,7 @@
#define _UAPI_LINUX_SHM_H_
#include <linux/ipc.h>
#include <linux/errno.h>
+#include <asm-generic/hugetlb_encode.h>
#include <unistd.h>
#define SHMMIN 1
#define SHMMNI 4096
@@ -42,6 +43,20 @@
#include <asm/shmbuf.h>
#define SHM_R 0400
#define SHM_W 0200
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+#define SHM_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT
+#define SHM_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK
+#define SHM_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB
+#define SHM_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB
+#define SHM_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB
+#define SHM_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB
+#define SHM_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB
+#define SHM_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB
+#define SHM_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB
+#define SHM_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB
+#define SHM_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB
+#define SHM_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB
#define SHM_RDONLY 010000
#define SHM_RND 020000
#define SHM_REMAP 040000
diff --git a/libc/kernel/uapi/linux/snmp.h b/libc/kernel/uapi/linux/snmp.h
index 91d693f..467a27a 100644
--- a/libc/kernel/uapi/linux/snmp.h
+++ b/libc/kernel/uapi/linux/snmp.h
@@ -152,12 +152,7 @@
LINUX_MIB_DELAYEDACKLOST,
LINUX_MIB_LISTENOVERFLOWS,
LINUX_MIB_LISTENDROPS,
- LINUX_MIB_TCPPREQUEUED,
- LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG,
- LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE,
- LINUX_MIB_TCPPREQUEUEDROPPED,
LINUX_MIB_TCPHPHITS,
- LINUX_MIB_TCPHPHITSTOUSER,
LINUX_MIB_TCPPUREACKS,
LINUX_MIB_TCPHPACKS,
LINUX_MIB_TCPRENORECOVERY,
@@ -176,14 +171,12 @@
LINUX_MIB_TCPSACKFAILURES,
LINUX_MIB_TCPLOSSFAILURES,
LINUX_MIB_TCPFASTRETRANS,
- LINUX_MIB_TCPFORWARDRETRANS,
LINUX_MIB_TCPSLOWSTARTRETRANS,
LINUX_MIB_TCPTIMEOUTS,
LINUX_MIB_TCPLOSSPROBES,
LINUX_MIB_TCPLOSSPROBERECOVERY,
LINUX_MIB_TCPRENORECOVERYFAIL,
LINUX_MIB_TCPSACKRECOVERYFAIL,
- LINUX_MIB_TCPSCHEDULERFAILED,
LINUX_MIB_TCPRCVCOLLAPSED,
LINUX_MIB_TCPDSACKOLDSENT,
LINUX_MIB_TCPDSACKOFOSENT,
@@ -196,6 +189,7 @@
LINUX_MIB_TCPABORTONLINGER,
LINUX_MIB_TCPABORTFAILED,
LINUX_MIB_TCPMEMORYPRESSURES,
+ LINUX_MIB_TCPMEMORYPRESSURESCHRONO,
LINUX_MIB_TCPSACKDISCARD,
LINUX_MIB_TCPDSACKIGNOREDOLD,
LINUX_MIB_TCPDSACKIGNOREDNOUNDO,
diff --git a/libc/kernel/uapi/linux/spi/spidev.h b/libc/kernel/uapi/linux/spi/spidev.h
index 73efc6f..2fe8264 100644
--- a/libc/kernel/uapi/linux/spi/spidev.h
+++ b/libc/kernel/uapi/linux/spi/spidev.h
@@ -19,6 +19,7 @@
#ifndef SPIDEV_H
#define SPIDEV_H
#include <linux/types.h>
+#include <linux/ioctl.h>
#define SPI_CPHA 0x01
#define SPI_CPOL 0x02
#define SPI_MODE_0 (0 | 0)
diff --git a/libc/kernel/uapi/linux/switchtec_ioctl.h b/libc/kernel/uapi/linux/switchtec_ioctl.h
index a0341a8..9337be6 100644
--- a/libc/kernel/uapi/linux/switchtec_ioctl.h
+++ b/libc/kernel/uapi/linux/switchtec_ioctl.h
@@ -38,6 +38,8 @@
__u32 num_partitions;
__u32 padding;
};
+#define SWITCHTEC_IOCTL_PART_ACTIVE 1
+#define SWITCHTEC_IOCTL_PART_RUNNING 2
struct switchtec_ioctl_flash_part_info {
__u32 flash_partition;
__u32 address;
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index 640e9c7..264b46f 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -71,6 +71,11 @@
TCMU_CMD_UNSPEC,
TCMU_CMD_ADDED_DEVICE,
TCMU_CMD_REMOVED_DEVICE,
+ TCMU_CMD_RECONFIG_DEVICE,
+ TCMU_CMD_ADDED_DEVICE_DONE,
+ TCMU_CMD_REMOVED_DEVICE_DONE,
+ TCMU_CMD_RECONFIG_DEVICE_DONE,
+ TCMU_CMD_SET_FEATURES,
__TCMU_CMD_MAX,
};
#define TCMU_CMD_MAX (__TCMU_CMD_MAX - 1)
@@ -78,6 +83,13 @@
TCMU_ATTR_UNSPEC,
TCMU_ATTR_DEVICE,
TCMU_ATTR_MINOR,
+ TCMU_ATTR_PAD,
+ TCMU_ATTR_DEV_CFG,
+ TCMU_ATTR_DEV_SIZE,
+ TCMU_ATTR_WRITECACHE,
+ TCMU_ATTR_CMD_STATUS,
+ TCMU_ATTR_DEVICE_ID,
+ TCMU_ATTR_SUPP_KERN_CMD_REPLY,
__TCMU_ATTR_MAX,
};
#define TCMU_ATTR_MAX (__TCMU_ATTR_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tc_act/tc_bpf.h b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
index 2e6f6d1..c4963a5 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_bpf.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_bpf.h
@@ -33,6 +33,7 @@
TCA_ACT_BPF_NAME,
TCA_ACT_BPF_PAD,
TCA_ACT_BPF_TAG,
+ TCA_ACT_BPF_ID,
__TCA_ACT_BPF_MAX,
};
#define TCA_ACT_BPF_MAX (__TCA_ACT_BPF_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
index 014a584..24e7403 100644
--- a/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
+++ b/libc/kernel/uapi/linux/tc_act/tc_tunnel_key.h
@@ -37,6 +37,7 @@
TCA_TUNNEL_KEY_ENC_KEY_ID,
TCA_TUNNEL_KEY_PAD,
TCA_TUNNEL_KEY_ENC_DST_PORT,
+ TCA_TUNNEL_KEY_NO_CSUM,
__TCA_TUNNEL_KEY_MAX,
};
#define TCA_TUNNEL_KEY_MAX (__TCA_TUNNEL_KEY_MAX - 1)
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 9c3a90d..f5134d6 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -85,6 +85,8 @@
#define TCP_SAVED_SYN 28
#define TCP_REPAIR_WINDOW 29
#define TCP_FASTOPEN_CONNECT 30
+#define TCP_ULP 31
+#define TCP_MD5SIG_EXT 32
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
@@ -175,13 +177,29 @@
TCP_NLA_SNDBUF_LIMITED,
TCP_NLA_DATA_SEGS_OUT,
TCP_NLA_TOTAL_RETRANS,
+ TCP_NLA_PACING_RATE,
+ TCP_NLA_DELIVERY_RATE,
+ TCP_NLA_SND_CWND,
+ TCP_NLA_REORDERING,
+ TCP_NLA_MIN_RTT,
+ TCP_NLA_RECUR_RETRANS,
+ TCP_NLA_DELIVERY_RATE_APP_LMT,
};
#define TCP_MD5SIG_MAXKEYLEN 80
+#define TCP_MD5SIG_FLAG_PREFIX 1
struct tcp_md5sig {
struct __kernel_sockaddr_storage tcpm_addr;
- __u16 __tcpm_pad1;
+ __u8 tcpm_flags;
+ __u8 tcpm_prefixlen;
__u16 tcpm_keylen;
- __u32 __tcpm_pad2;
+ __u32 __tcpm_pad;
+ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+struct tcp_diag_md5sig {
+ __u8 tcpm_family;
+ __u8 tcpm_prefixlen;
+ __u16 tcpm_keylen;
+ __be32 tcpm_addr[4];
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
};
#endif
diff --git a/libc/kernel/uapi/linux/tee.h b/libc/kernel/uapi/linux/tee.h
index 9a42337..20d0d80 100644
--- a/libc/kernel/uapi/linux/tee.h
+++ b/libc/kernel/uapi/linux/tee.h
@@ -26,6 +26,7 @@
#define TEE_IOCTL_SHM_DMA_BUF 0x2
#define TEE_MAX_ARG_SIZE 1024
#define TEE_GEN_CAP_GP (1 << 0)
+#define TEE_GEN_CAP_PRIVILEGED (1 << 1)
#define TEE_IMPL_ID_OPTEE 1
#define TEE_OPTEE_CAP_TZ (1 << 0)
struct tee_ioctl_version_data {
diff --git a/libc/kernel/uapi/linux/tls.h b/libc/kernel/uapi/linux/tls.h
new file mode 100644
index 0000000..73618e0
--- /dev/null
+++ b/libc/kernel/uapi/linux/tls.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_TLS_H
+#define _UAPI_LINUX_TLS_H
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <linux/socket.h>
+#include <linux/tcp.h>
+#include <net/tcp.h>
+#define TLS_TX 1
+#define TLS_VERSION_MINOR(ver) ((ver) & 0xFF)
+#define TLS_VERSION_MAJOR(ver) (((ver) >> 8) & 0xFF)
+#define TLS_VERSION_NUMBER(id) ((((id ##_VERSION_MAJOR) & 0xFF) << 8) | ((id ##_VERSION_MINOR) & 0xFF))
+#define TLS_1_2_VERSION_MAJOR 0x3
+#define TLS_1_2_VERSION_MINOR 0x3
+#define TLS_1_2_VERSION TLS_VERSION_NUMBER(TLS_1_2)
+#define TLS_CIPHER_AES_GCM_128 51
+#define TLS_CIPHER_AES_GCM_128_IV_SIZE 8
+#define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16
+#define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4
+#define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16
+#define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8
+#define TLS_SET_RECORD_TYPE 1
+struct tls_crypto_info {
+ __u16 version;
+ __u16 cipher_type;
+};
+struct tls12_crypto_info_aes_gcm_128 {
+ struct tls_crypto_info info;
+ unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE];
+ unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE];
+ unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE];
+ unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE];
+};
+#endif
diff --git a/libc/kernel/uapi/linux/tty.h b/libc/kernel/uapi/linux/tty.h
index 9a09303..48fa908 100644
--- a/libc/kernel/uapi/linux/tty.h
+++ b/libc/kernel/uapi/linux/tty.h
@@ -45,4 +45,6 @@
#define N_TRACESINK 23
#define N_TRACEROUTER 24
#define N_NCI 25
+#define N_SPEAKUP 26
+#define N_NULL 27
#endif
diff --git a/libc/kernel/uapi/linux/usb/audio.h b/libc/kernel/uapi/linux/usb/audio.h
index 7f961fc..121c859 100644
--- a/libc/kernel/uapi/linux/usb/audio.h
+++ b/libc/kernel/uapi/linux/usb/audio.h
@@ -186,7 +186,7 @@
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
- __u16 wProcessType;
+ __le16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__((packed));
@@ -260,8 +260,8 @@
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
- __u16 wMaxBitRate;
- __u16 wSamplesPerFrame;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
} __attribute__((packed));
diff --git a/libc/kernel/uapi/linux/usb/ch9.h b/libc/kernel/uapi/linux/usb/ch9.h
index f06a970..38e7ae7 100644
--- a/libc/kernel/uapi/linux/usb/ch9.h
+++ b/libc/kernel/uapi/linux/usb/ch9.h
@@ -305,6 +305,7 @@
__u8 bFunctionProtocol;
__u8 iFunction;
} __attribute__((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
struct usb_security_descriptor {
__u8 bLength;
__u8 bDescriptorType;
diff --git a/libc/kernel/uapi/linux/wil6210_uapi.h b/libc/kernel/uapi/linux/usb/charger.h
similarity index 62%
rename from libc/kernel/uapi/linux/wil6210_uapi.h
rename to libc/kernel/uapi/linux/usb/charger.h
index e68b6c8..0810aab 100644
--- a/libc/kernel/uapi/linux/wil6210_uapi.h
+++ b/libc/kernel/uapi/linux/usb/charger.h
@@ -16,30 +16,18 @@
***
****************************************************************************
****************************************************************************/
-#ifndef __WIL6210_UAPI_H__
-#define __WIL6210_UAPI_H__
-#define __user
-#include <linux/sockios.h>
-#define WIL_IOCTL_MEMIO (SIOCDEVPRIVATE + 2)
-#define WIL_IOCTL_MEMIO_BLOCK (SIOCDEVPRIVATE + 3)
-enum wil_memio_op {
- wil_mmio_read = 0,
- wil_mmio_write = 1,
- wil_mmio_op_mask = 0xff,
- wil_mmio_addr_linker = 0 << 8,
- wil_mmio_addr_ahb = 1 << 8,
- wil_mmio_addr_bar = 2 << 8,
- wil_mmio_addr_mask = 0xff00,
+#ifndef _UAPI__LINUX_USB_CHARGER_H
+#define _UAPI__LINUX_USB_CHARGER_H
+enum usb_charger_type {
+ UNKNOWN_TYPE,
+ SDP_TYPE,
+ DCP_TYPE,
+ CDP_TYPE,
+ ACA_TYPE,
};
-struct wil_memio {
- uint32_t op;
- uint32_t addr;
- uint32_t val;
-};
-struct wil_memio_block {
- uint32_t op;
- uint32_t addr;
- uint32_t size;
- void __user * block;
+enum usb_charger_state {
+ USB_CHARGER_DEFAULT,
+ USB_CHARGER_PRESENT,
+ USB_CHARGER_ABSENT,
};
#endif
diff --git a/libc/kernel/uapi/linux/usbdevice_fs.h b/libc/kernel/uapi/linux/usbdevice_fs.h
index 76b5f68..87afabe 100644
--- a/libc/kernel/uapi/linux/usbdevice_fs.h
+++ b/libc/kernel/uapi/linux/usbdevice_fs.h
@@ -147,4 +147,5 @@
#define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams)
#define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams)
#define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32)
+#define USBDEVFS_GET_SPEED _IO('U', 31)
#endif
diff --git a/libc/kernel/uapi/linux/userfaultfd.h b/libc/kernel/uapi/linux/userfaultfd.h
index caa1eb4..ecc6302 100644
--- a/libc/kernel/uapi/linux/userfaultfd.h
+++ b/libc/kernel/uapi/linux/userfaultfd.h
@@ -20,7 +20,7 @@
#define _LINUX_USERFAULTFD_H
#include <linux/types.h>
#define UFFD_API ((__u64) 0xAA)
-#define UFFD_API_FEATURES (UFFD_FEATURE_EVENT_FORK | UFFD_FEATURE_EVENT_REMAP | UFFD_FEATURE_EVENT_REMOVE | UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_MISSING_HUGETLBFS | UFFD_FEATURE_MISSING_SHMEM)
+#define UFFD_API_FEATURES (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)
#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)
#define UFFD_API_RANGE_IOCTLS_BASIC ((__u64) 1 << _UFFDIO_WAKE | (__u64) 1 << _UFFDIO_COPY)
@@ -46,6 +46,9 @@
struct {
__u64 flags;
__u64 address;
+ union {
+ __u32 ptid;
+ } feat;
} pagefault;
struct {
__u32 ufd;
@@ -82,6 +85,8 @@
#define UFFD_FEATURE_MISSING_HUGETLBFS (1 << 4)
#define UFFD_FEATURE_MISSING_SHMEM (1 << 5)
#define UFFD_FEATURE_EVENT_UNMAP (1 << 6)
+#define UFFD_FEATURE_SIGBUS (1 << 7)
+#define UFFD_FEATURE_THREAD_ID (1 << 8)
__u64 features;
__u64 ioctls;
};
diff --git a/libc/kernel/uapi/linux/uuid.h b/libc/kernel/uapi/linux/uuid.h
index c48b6d3..808578f 100644
--- a/libc/kernel/uapi/linux/uuid.h
+++ b/libc/kernel/uapi/linux/uuid.h
@@ -22,16 +22,11 @@
#include <linux/string.h>
typedef struct {
__u8 b[16];
-} uuid_le;
-typedef struct {
- __u8 b[16];
-} uuid_be;
-#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_le) \
+} guid_t;
+#define GUID_INIT(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((guid_t) \
{ { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
-#define UUID_BE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
-((uuid_be) \
-{ { ((a) >> 24) & 0xff, ((a) >> 16) & 0xff, ((a) >> 8) & 0xff, (a) & 0xff, ((b) >> 8) & 0xff, (b) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff, (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } })
+typedef guid_t uuid_le;
+#define UUID_LE(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
#define NULL_UUID_LE UUID_LE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-#define NULL_UUID_BE UUID_BE(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
#endif
diff --git a/libc/kernel/uapi/linux/v4l2-controls.h b/libc/kernel/uapi/linux/v4l2-controls.h
index 8b69770..302da8f 100644
--- a/libc/kernel/uapi/linux/v4l2-controls.h
+++ b/libc/kernel/uapi/linux/v4l2-controls.h
@@ -107,6 +107,8 @@
#define V4L2_CID_USER_SAA7134_BASE (V4L2_CID_USER_BASE + 0x1060)
#define V4L2_CID_USER_ADV7180_BASE (V4L2_CID_USER_BASE + 0x1070)
#define V4L2_CID_USER_TC358743_BASE (V4L2_CID_USER_BASE + 0x1080)
+#define V4L2_CID_USER_MAX217X_BASE (V4L2_CID_USER_BASE + 0x1090)
+#define V4L2_CID_USER_IMX_BASE (V4L2_CID_USER_BASE + 0x1090)
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE + 0)
@@ -744,6 +746,7 @@
#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
#define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3)
#define V4L2_CID_DEINTERLACING_MODE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 4)
+#define V4L2_CID_DIGITAL_GAIN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 5)
#define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900)
#define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1)
#define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1)
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index 73eb988..7714cb7 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 265219
+#define LINUX_VERSION_CODE 265728
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/kernel/uapi/linux/videodev2.h b/libc/kernel/uapi/linux/videodev2.h
index 25e2fe8..c350108 100644
--- a/libc/kernel/uapi/linux/videodev2.h
+++ b/libc/kernel/uapi/linux/videodev2.h
@@ -288,6 +288,10 @@
#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2')
#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2')
#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2')
+#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C')
+#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C')
+#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C')
+#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C')
#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2')
#define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6')
#define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6')
@@ -346,6 +350,9 @@
#define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8')
#define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4')
#define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2')
+#define V4L2_SDR_FMT_PCU16BE v4l2_fourcc('P', 'C', '1', '6')
+#define V4L2_SDR_FMT_PCU18BE v4l2_fourcc('P', 'C', '1', '8')
+#define V4L2_SDR_FMT_PCU20BE v4l2_fourcc('P', 'C', '2', '0')
#define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6')
#define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8')
#define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6')
diff --git a/libc/kernel/uapi/linux/vtpm_proxy.h b/libc/kernel/uapi/linux/vtpm_proxy.h
index 15e39f2..0ab0536 100644
--- a/libc/kernel/uapi/linux/vtpm_proxy.h
+++ b/libc/kernel/uapi/linux/vtpm_proxy.h
@@ -31,4 +31,6 @@
__u32 minor;
};
#define VTPM_PROXY_IOC_NEW_DEV _IOWR(0xa1, 0x00, struct vtpm_proxy_new_dev)
+#define TPM2_CC_SET_LOCALITY 0x20001000
+#define TPM_ORD_SET_LOCALITY 0x20001000
#endif
diff --git a/libc/kernel/uapi/linux/xfrm.h b/libc/kernel/uapi/linux/xfrm.h
index 4ff9bea..5ec7193 100644
--- a/libc/kernel/uapi/linux/xfrm.h
+++ b/libc/kernel/uapi/linux/xfrm.h
@@ -258,6 +258,7 @@
XFRMA_ADDRESS_FILTER,
XFRMA_PAD,
XFRMA_OFFLOAD_DEV,
+ XFRMA_OUTPUT_MARK,
__XFRMA_MAX
#define XFRMA_MAX (__XFRMA_MAX - 1)
};
diff --git a/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
new file mode 100644
index 0000000..766fe4c
--- /dev/null
+++ b/libc/kernel/uapi/rdma/ib_user_ioctl_verbs.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** To edit the content of this header, modify the corresponding
+ *** source file (e.g. under external/kernel-headers/original/) then
+ *** run bionic/libc/kernel/tools/update_all.py
+ ***
+ *** Any manual change here will be lost the next time this script will
+ *** be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef IB_USER_IOCTL_VERBS_H
+#define IB_USER_IOCTL_VERBS_H
+#include <rdma/rdma_user_ioctl.h>
+#define UVERBS_UDATA_DRIVER_DATA_NS 1
+#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_NS_SHIFT)
+enum uverbs_default_objects {
+ UVERBS_OBJECT_DEVICE,
+ UVERBS_OBJECT_PD,
+ UVERBS_OBJECT_COMP_CHANNEL,
+ UVERBS_OBJECT_CQ,
+ UVERBS_OBJECT_QP,
+ UVERBS_OBJECT_SRQ,
+ UVERBS_OBJECT_AH,
+ UVERBS_OBJECT_MR,
+ UVERBS_OBJECT_MW,
+ UVERBS_OBJECT_FLOW,
+ UVERBS_OBJECT_XRCD,
+ UVERBS_OBJECT_RWQ_IND_TBL,
+ UVERBS_OBJECT_WQ,
+ UVERBS_OBJECT_LAST,
+};
+enum {
+ UVERBS_UHW_IN = UVERBS_UDATA_DRIVER_DATA_FLAG,
+ UVERBS_UHW_OUT,
+};
+enum uverbs_create_cq_cmd_attr_ids {
+ CREATE_CQ_HANDLE,
+ CREATE_CQ_CQE,
+ CREATE_CQ_USER_HANDLE,
+ CREATE_CQ_COMP_CHANNEL,
+ CREATE_CQ_COMP_VECTOR,
+ CREATE_CQ_FLAGS,
+ CREATE_CQ_RESP_CQE,
+};
+enum uverbs_destroy_cq_cmd_attr_ids {
+ DESTROY_CQ_HANDLE,
+ DESTROY_CQ_RESP,
+};
+enum uverbs_actions_cq_ops {
+ UVERBS_CQ_CREATE,
+ UVERBS_CQ_DESTROY,
+};
+#endif
diff --git a/libc/kernel/uapi/rdma/ib_user_verbs.h b/libc/kernel/uapi/rdma/ib_user_verbs.h
index 4feb031..ff3ebcb 100644
--- a/libc/kernel/uapi/rdma/ib_user_verbs.h
+++ b/libc/kernel/uapi/rdma/ib_user_verbs.h
@@ -174,6 +174,14 @@
__u32 max_rwq_indirection_table_size;
__u32 reserved;
};
+struct ib_uverbs_tm_caps {
+ __u32 max_rndv_hdr_size;
+ __u32 max_num_tags;
+ __u32 flags;
+ __u32 max_ops;
+ __u32 max_sge;
+ __u32 reserved;
+};
struct ib_uverbs_ex_query_device_resp {
struct ib_uverbs_query_device_resp base;
__u32 comp_mask;
@@ -185,6 +193,7 @@
struct ib_uverbs_rss_caps rss_caps;
__u32 max_wq_type_rq;
__u32 raw_packet_caps;
+ struct ib_uverbs_tm_caps tm_caps;
};
struct ib_uverbs_query_port {
__u64 response;
@@ -467,7 +476,7 @@
__u32 comp_mask;
__u32 create_flags;
__u32 rwq_ind_tbl_handle;
- __u32 reserved1;
+ __u32 source_qpn;
};
struct ib_uverbs_open_qp {
__u64 response;
@@ -852,7 +861,7 @@
__u32 max_wr;
__u32 max_sge;
__u32 srq_limit;
- __u32 reserved;
+ __u32 max_num_tags;
__u32 xrcd_handle;
__u32 cq_handle;
__u64 driver_data[0];
diff --git a/libc/kernel/uapi/rdma/mlx4-abi.h b/libc/kernel/uapi/rdma/mlx4-abi.h
index 232d835..078b386 100644
--- a/libc/kernel/uapi/rdma/mlx4-abi.h
+++ b/libc/kernel/uapi/rdma/mlx4-abi.h
@@ -56,12 +56,49 @@
__u32 srqn;
__u32 reserved;
};
+struct mlx4_ib_create_qp_rss {
+ __u64 rx_hash_fields_mask;
+ __u8 rx_hash_function;
+ __u8 reserved[7];
+ __u8 rx_hash_key[40];
+ __u32 comp_mask;
+ __u32 reserved1;
+};
struct mlx4_ib_create_qp {
__u64 buf_addr;
__u64 db_addr;
__u8 log_sq_bb_count;
__u8 log_sq_stride;
__u8 sq_no_prefetch;
- __u8 reserved[5];
+ __u8 reserved;
+ __u32 inl_recv_sz;
+};
+struct mlx4_ib_create_wq {
+ __u64 buf_addr;
+ __u64 db_addr;
+ __u8 log_range_size;
+ __u8 reserved[3];
+ __u32 comp_mask;
+};
+struct mlx4_ib_modify_wq {
+ __u32 comp_mask;
+ __u32 reserved;
+};
+struct mlx4_ib_create_rwq_ind_tbl_resp {
+ __u32 response_length;
+ __u32 reserved;
+};
+enum mlx4_ib_rx_hash_function_flags {
+ MLX4_IB_RX_HASH_FUNC_TOEPLITZ = 1 << 0,
+};
+enum mlx4_ib_rx_hash_fields {
+ MLX4_IB_RX_HASH_SRC_IPV4 = 1 << 0,
+ MLX4_IB_RX_HASH_DST_IPV4 = 1 << 1,
+ MLX4_IB_RX_HASH_SRC_IPV6 = 1 << 2,
+ MLX4_IB_RX_HASH_DST_IPV6 = 1 << 3,
+ MLX4_IB_RX_HASH_SRC_PORT_TCP = 1 << 4,
+ MLX4_IB_RX_HASH_DST_PORT_TCP = 1 << 5,
+ MLX4_IB_RX_HASH_SRC_PORT_UDP = 1 << 6,
+ MLX4_IB_RX_HASH_DST_PORT_UDP = 1 << 7
};
#endif
diff --git a/libc/kernel/uapi/rdma/mlx5-abi.h b/libc/kernel/uapi/rdma/mlx5-abi.h
index 6e76a3d..b51ff4e 100644
--- a/libc/kernel/uapi/rdma/mlx5-abi.h
+++ b/libc/kernel/uapi/rdma/mlx5-abi.h
@@ -112,6 +112,20 @@
__u32 supported_qpts;
__u32 reserved;
};
+enum mlx5_ib_mpw_caps {
+ MPW_RESERVED = 1 << 0,
+ MLX5_IB_ALLOW_MPW = 1 << 1,
+ MLX5_IB_SUPPORT_EMPW = 1 << 2,
+};
+enum mlx5_ib_sw_parsing_offloads {
+ MLX5_IB_SW_PARSING = 1 << 0,
+ MLX5_IB_SW_PARSING_CSUM = 1 << 1,
+ MLX5_IB_SW_PARSING_LSO = 1 << 2,
+};
+struct mlx5_ib_sw_parsing_caps {
+ __u32 sw_parsing_offloads;
+ __u32 supported_qpts;
+};
struct mlx5_ib_query_device_resp {
__u32 comp_mask;
__u32 response_length;
@@ -121,6 +135,7 @@
struct mlx5_packet_pacing_caps packet_pacing_caps;
__u32 mlx5_ib_support_multi_pkt_send_wqes;
__u32 reserved;
+ struct mlx5_ib_sw_parsing_caps sw_parsing_caps;
};
struct mlx5_ib_create_cq {
__u64 buf_addr;
diff --git a/libc/kernel/uapi/rdma/qedr-abi.h b/libc/kernel/uapi/rdma/qedr-abi.h
index 597391f..55af44b 100644
--- a/libc/kernel/uapi/rdma/qedr-abi.h
+++ b/libc/kernel/uapi/rdma/qedr-abi.h
@@ -30,6 +30,9 @@
__u32 sges_per_recv_wr;
__u32 sges_per_srq_wr;
__u32 max_cqes;
+ __u8 dpm_enabled;
+ __u8 wids_enabled;
+ __u16 wid_count;
};
struct qedr_alloc_pd_ureq {
__u64 rsvd1;
diff --git a/libc/kernel/uapi/rdma/rdma_netlink.h b/libc/kernel/uapi/rdma/rdma_netlink.h
index ae261d7..c7bcb6d 100644
--- a/libc/kernel/uapi/rdma/rdma_netlink.h
+++ b/libc/kernel/uapi/rdma/rdma_netlink.h
@@ -24,7 +24,7 @@
RDMA_NL_IWCM,
RDMA_NL_RSVD,
RDMA_NL_LS,
- RDMA_NL_I40IW,
+ RDMA_NL_NLDEV,
RDMA_NL_NUM_CLIENTS
};
enum {
@@ -170,4 +170,34 @@
struct rdma_nla_ls_gid {
__u8 gid[16];
};
+enum rdma_nldev_command {
+ RDMA_NLDEV_CMD_UNSPEC,
+ RDMA_NLDEV_CMD_GET,
+ RDMA_NLDEV_CMD_SET,
+ RDMA_NLDEV_CMD_NEW,
+ RDMA_NLDEV_CMD_DEL,
+ RDMA_NLDEV_CMD_PORT_GET,
+ RDMA_NLDEV_CMD_PORT_SET,
+ RDMA_NLDEV_CMD_PORT_NEW,
+ RDMA_NLDEV_CMD_PORT_DEL,
+ RDMA_NLDEV_NUM_OPS
+};
+enum rdma_nldev_attr {
+ RDMA_NLDEV_ATTR_UNSPEC,
+ RDMA_NLDEV_ATTR_DEV_INDEX,
+ RDMA_NLDEV_ATTR_DEV_NAME,
+ RDMA_NLDEV_ATTR_PORT_INDEX,
+ RDMA_NLDEV_ATTR_CAP_FLAGS,
+ RDMA_NLDEV_ATTR_FW_VERSION,
+ RDMA_NLDEV_ATTR_NODE_GUID,
+ RDMA_NLDEV_ATTR_SYS_IMAGE_GUID,
+ RDMA_NLDEV_ATTR_SUBNET_PREFIX,
+ RDMA_NLDEV_ATTR_LID,
+ RDMA_NLDEV_ATTR_SM_LID,
+ RDMA_NLDEV_ATTR_LMC,
+ RDMA_NLDEV_ATTR_PORT_STATE,
+ RDMA_NLDEV_ATTR_PORT_PHYS_STATE,
+ RDMA_NLDEV_ATTR_DEV_NODE_TYPE,
+ RDMA_NLDEV_ATTR_MAX
+};
#endif
diff --git a/libc/kernel/uapi/rdma/rdma_user_ioctl.h b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
index bb65c5d..41c11bc 100644
--- a/libc/kernel/uapi/rdma/rdma_user_ioctl.h
+++ b/libc/kernel/uapi/rdma/rdma_user_ioctl.h
@@ -24,6 +24,28 @@
#include <rdma/hfi/hfi1_ioctl.h>
#define RDMA_IOCTL_MAGIC 0x1b
#define IB_IOCTL_MAGIC RDMA_IOCTL_MAGIC
+#define RDMA_VERBS_IOCTL _IOWR(RDMA_IOCTL_MAGIC, 1, struct ib_uverbs_ioctl_hdr)
+#define UVERBS_ID_NS_MASK 0xF000
+#define UVERBS_ID_NS_SHIFT 12
+enum {
+ UVERBS_ATTR_F_MANDATORY = 1U << 0,
+ UVERBS_ATTR_F_VALID_OUTPUT = 1U << 1,
+};
+struct ib_uverbs_attr {
+ __u16 attr_id;
+ __u16 len;
+ __u16 flags;
+ __u16 reserved;
+ __u64 data;
+};
+struct ib_uverbs_ioctl_hdr {
+ __u16 length;
+ __u16 object_id;
+ __u16 method_id;
+ __u16 num_attrs;
+ __u64 reserved;
+ struct ib_uverbs_attr attrs[0];
+};
#define IB_USER_MAD_REGISTER_AGENT _IOWR(RDMA_IOCTL_MAGIC, 0x01, struct ib_user_mad_reg_req)
#define IB_USER_MAD_UNREGISTER_AGENT _IOW(RDMA_IOCTL_MAGIC, 0x02, __u32)
#define IB_USER_MAD_ENABLE_PKEY _IO(RDMA_IOCTL_MAGIC, 0x03)
diff --git a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
index 3666815..2062366 100644
--- a/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
+++ b/libc/kernel/uapi/rdma/vmw_pvrdma-abi.h
@@ -92,7 +92,8 @@
PVRDMA_WC_IP_CSUM_OK = 1 << 3,
PVRDMA_WC_WITH_SMAC = 1 << 4,
PVRDMA_WC_WITH_VLAN = 1 << 5,
- PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_VLAN,
+ PVRDMA_WC_WITH_NETWORK_HDR_TYPE = 1 << 6,
+ PVRDMA_WC_FLAGS_MAX = PVRDMA_WC_WITH_NETWORK_HDR_TYPE,
};
struct pvrdma_alloc_ucontext_resp {
__u32 qp_tab_size;
@@ -226,6 +227,7 @@
__u8 dlid_path_bits;
__u8 port_num;
__u8 smac[6];
- __u8 reserved2[7];
+ __u8 network_hdr_type;
+ __u8 reserved2[6];
};
#endif
diff --git a/libc/kernel/uapi/scsi/cxlflash_ioctl.h b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
index 91ffe62..9781905 100644
--- a/libc/kernel/uapi/scsi/cxlflash_ioctl.h
+++ b/libc/kernel/uapi/scsi/cxlflash_ioctl.h
@@ -19,6 +19,7 @@
#ifndef _CXLFLASH_IOCTL_H
#define _CXLFLASH_IOCTL_H
#include <linux/types.h>
+#define CXLFLASH_WWID_LEN 16
#define DK_CXLFLASH_VERSION_0 0
struct dk_cxlflash_hdr {
__u16 version;
@@ -104,7 +105,7 @@
__u64 adap_fd;
__u64 reserved[8];
};
-#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN 16
+#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN CXLFLASH_WWID_LEN
#define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL
#define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL
#define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL
@@ -138,4 +139,48 @@
#define DK_CXLFLASH_USER_VIRTUAL CXL_IOWR(0x87, dk_cxlflash_uvirtual)
#define DK_CXLFLASH_VLUN_RESIZE CXL_IOWR(0x88, dk_cxlflash_resize)
#define DK_CXLFLASH_VLUN_CLONE CXL_IOWR(0x89, dk_cxlflash_clone)
+#define HT_CXLFLASH_VERSION_0 0
+struct ht_cxlflash_hdr {
+ __u16 version;
+ __u16 subcmd;
+ __u16 rsvd[2];
+ __u64 flags;
+ __u64 return_flags;
+};
+#define HT_CXLFLASH_HOST_READ 0x0000000000000000ULL
+#define HT_CXLFLASH_HOST_WRITE 0x0000000000000001ULL
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_CREATE_LUN 0x0001
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_DELETE_LUN 0x0002
+#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_QUERY_PORT 0x0003
+struct ht_cxlflash_lun_provision {
+ struct ht_cxlflash_hdr hdr;
+ __u16 port;
+ __u16 reserved16[3];
+ __u64 size;
+ __u64 lun_id;
+ __u8 wwid[CXLFLASH_WWID_LEN];
+ __u64 max_num_luns;
+ __u64 cur_num_luns;
+ __u64 max_cap_port;
+ __u64 cur_cap_port;
+ __u64 reserved[8];
+};
+#define HT_CXLFLASH_AFU_DEBUG_MAX_DATA_LEN 262144
+#define HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN 12
+struct ht_cxlflash_afu_debug {
+ struct ht_cxlflash_hdr hdr;
+ __u8 reserved8[4];
+ __u8 afu_subcmd[HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN];
+ __u64 data_ea;
+ __u32 data_len;
+ __u32 reserved32;
+ __u64 reserved[8];
+};
+union cxlflash_ht_ioctls {
+ struct ht_cxlflash_lun_provision lun_provision;
+ struct ht_cxlflash_afu_debug afu_debug;
+};
+#define MAX_HT_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ht_ioctls))
+#define HT_CXLFLASH_LUN_PROVISION CXL_IOWR(0xBF, ht_cxlflash_lun_provision)
+#define HT_CXLFLASH_AFU_DEBUG CXL_IOWR(0xBE, ht_cxlflash_afu_debug)
#endif
diff --git a/libc/kernel/uapi/sound/asoc.h b/libc/kernel/uapi/sound/asoc.h
index 35e1b15..d0bab8b 100644
--- a/libc/kernel/uapi/sound/asoc.h
+++ b/libc/kernel/uapi/sound/asoc.h
@@ -53,7 +53,15 @@
#define SND_SOC_TPLG_DAPM_DAI_IN 13
#define SND_SOC_TPLG_DAPM_DAI_OUT 14
#define SND_SOC_TPLG_DAPM_DAI_LINK 15
-#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DAI_LINK
+#define SND_SOC_TPLG_DAPM_BUFFER 16
+#define SND_SOC_TPLG_DAPM_SCHEDULER 17
+#define SND_SOC_TPLG_DAPM_EFFECT 18
+#define SND_SOC_TPLG_DAPM_SIGGEN 19
+#define SND_SOC_TPLG_DAPM_SRC 20
+#define SND_SOC_TPLG_DAPM_ASRC 21
+#define SND_SOC_TPLG_DAPM_ENCODER 22
+#define SND_SOC_TPLG_DAPM_DECODER 23
+#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DECODER
#define SND_SOC_TPLG_MAGIC 0x41536F43
#define SND_SOC_TPLG_NUM_TEXTS 16
#define SND_SOC_TPLG_ABI_VERSION 0x5
diff --git a/libc/kernel/uapi/sound/asound.h b/libc/kernel/uapi/sound/asound.h
index e3041ce..63f66b4 100644
--- a/libc/kernel/uapi/sound/asound.h
+++ b/libc/kernel/uapi/sound/asound.h
@@ -100,7 +100,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, 13)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14)
typedef unsigned long snd_pcm_uframes_t;
typedef signed long snd_pcm_sframes_t;
enum {
@@ -205,6 +205,7 @@
#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002
#define SNDRV_PCM_INFO_DOUBLE 0x00000004
#define SNDRV_PCM_INFO_BATCH 0x00000010
+#define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020
#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100
#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200
#define SNDRV_PCM_INFO_COMPLEX 0x00000400
@@ -446,6 +447,7 @@
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info)
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int)
+#define SNDRV_PCM_IOCTL_USER_PVERSION _IOW('A', 0x04, int)
#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params)
#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params)
#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
diff --git a/libc/kernel/uapi/sound/snd_sst_tokens.h b/libc/kernel/uapi/sound/snd_sst_tokens.h
index 13ae705..a4cfdd5 100644
--- a/libc/kernel/uapi/sound/snd_sst_tokens.h
+++ b/libc/kernel/uapi/sound/snd_sst_tokens.h
@@ -68,6 +68,31 @@
SKL_TKN_STR_LIB_NAME,
SKL_TKN_U32_PMODE,
SKL_TKL_U32_D0I3_CAPS,
- SKL_TKN_MAX = SKL_TKL_U32_D0I3_CAPS,
+ SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS,
+ SKL_TKN_U32_DMA_BUF_SIZE,
+ SKL_TKN_U32_PIPE_DIRECTION,
+ SKL_TKN_U32_PIPE_CONFIG_ID,
+ SKL_TKN_U32_NUM_CONFIGS,
+ SKL_TKN_U32_PATH_MEM_PGS,
+ SKL_TKN_U32_CFG_FREQ,
+ SKL_TKN_U8_CFG_CHAN,
+ SKL_TKN_U8_CFG_BPS,
+ SKL_TKN_CFG_MOD_RES_ID,
+ SKL_TKN_CFG_MOD_FMT_ID,
+ SKL_TKN_U8_NUM_MOD,
+ SKL_TKN_MM_U8_MOD_IDX,
+ SKL_TKN_MM_U8_NUM_RES,
+ SKL_TKN_MM_U8_NUM_INTF,
+ SKL_TKN_MM_U32_RES_ID,
+ SKL_TKN_MM_U32_CPS,
+ SKL_TKN_MM_U32_DMA_SIZE,
+ SKL_TKN_MM_U32_CPC,
+ SKL_TKN_MM_U32_RES_PIN_ID,
+ SKL_TKN_MM_U32_INTF_PIN_ID,
+ SKL_TKN_MM_U32_PIN_BUF,
+ SKL_TKN_MM_U32_FMT_ID,
+ SKL_TKN_MM_U32_NUM_IN_FMT,
+ SKL_TKN_MM_U32_NUM_OUT_FMT,
+ SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT,
};
#endif
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index a3a3ece..979a704 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -78,4 +78,20 @@
#define BIONIC_STOP_UNWIND asm volatile(".cfi_undefined $ra")
#endif
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example. If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function.
+//
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template <typename T, size_t N>
+char (&ArraySizeHelper(T (&array)[N]))[N]; // NOLINT(readability/casting)
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
#endif // _BIONIC_MACROS_H_
diff --git a/libc/system_properties/context_node.cpp b/libc/system_properties/context_node.cpp
new file mode 100644
index 0000000..13cef75
--- /dev/null
+++ b/libc/system_properties/context_node.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "context_node.h"
+
+#include <unistd.h>
+
+#include <async_safe/log.h>
+
+#include "property_filename.h"
+
+// pthread_mutex_lock() calls into system_properties in the case of contention.
+// This creates a risk of dead lock if any system_properties functions
+// use pthread locks after system_property initialization.
+//
+// For this reason, the below three functions use a bionic Lock and static
+// allocation of memory for each filename.
+
+bool ContextNode::Open(bool access_rw, bool* fsetxattr_failed) {
+ lock_.lock();
+ if (pa_) {
+ lock_.unlock();
+ return true;
+ }
+
+ char filename[PROP_FILENAME_MAX];
+ int len =
+ async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_);
+ if (len < 0 || len > PROP_FILENAME_MAX) {
+ lock_.unlock();
+ return false;
+ }
+
+ if (access_rw) {
+ pa_ = prop_area::map_prop_area_rw(filename, context_, fsetxattr_failed);
+ } else {
+ pa_ = prop_area::map_prop_area(filename);
+ }
+ lock_.unlock();
+ return pa_;
+}
+
+bool ContextNode::CheckAccessAndOpen() {
+ if (!pa_ && !no_access_) {
+ if (!CheckAccess() || !Open(false, nullptr)) {
+ no_access_ = true;
+ }
+ }
+ return pa_;
+}
+
+void ContextNode::ResetAccess() {
+ if (!CheckAccess()) {
+ Unmap();
+ no_access_ = true;
+ } else {
+ no_access_ = false;
+ }
+}
+
+bool ContextNode::CheckAccess() {
+ char filename[PROP_FILENAME_MAX];
+ int len =
+ async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_);
+ if (len < 0 || len > PROP_FILENAME_MAX) {
+ return false;
+ }
+
+ return access(filename, R_OK) == 0;
+}
+
+void ContextNode::Unmap() {
+ prop_area::unmap_prop_area(&pa_);
+}
diff --git a/libc/system_properties/context_node.h b/libc/system_properties/context_node.h
new file mode 100644
index 0000000..1c6cbbb
--- /dev/null
+++ b/libc/system_properties/context_node.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXT_NODE_H
+#define SYSTEM_PROPERTIES_CONTEXT_NODE_H
+
+#include "private/bionic_lock.h"
+
+#include "prop_area.h"
+
+class ContextNode {
+ public:
+ ContextNode(const char* context) : context_(context), pa_(nullptr), no_access_(false) {
+ lock_.init(false);
+ }
+ ~ContextNode() {
+ Unmap();
+ }
+ bool Open(bool access_rw, bool* fsetxattr_failed);
+ bool CheckAccessAndOpen();
+ void ResetAccess();
+
+ const char* context() const {
+ return context_;
+ }
+ prop_area* pa() {
+ return pa_;
+ }
+
+ private:
+ bool CheckAccess();
+ void Unmap();
+
+ Lock lock_;
+ const char* context_;
+ prop_area* pa_;
+ bool no_access_;
+};
+
+#endif
diff --git a/libc/system_properties/contexts.h b/libc/system_properties/contexts.h
new file mode 100644
index 0000000..5df9d96
--- /dev/null
+++ b/libc/system_properties/contexts.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_H
+#define SYSTEM_PROPERTIES_CONTEXTS_H
+
+#include "prop_area.h"
+#include "prop_info.h"
+
+class Contexts {
+ public:
+ virtual ~Contexts() {
+ }
+
+ virtual bool Initialize(bool writable) = 0;
+ virtual prop_area* GetPropAreaForName(const char* name) = 0;
+ virtual prop_area* GetSerialPropArea() = 0;
+ virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) = 0;
+ virtual void ResetAccess() = 0;
+ virtual void FreeAndUnmap() = 0;
+};
+
+#endif
diff --git a/libc/system_properties/contexts_pre_split.h b/libc/system_properties/contexts_pre_split.h
new file mode 100644
index 0000000..bbc8529
--- /dev/null
+++ b/libc/system_properties/contexts_pre_split.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
+#define SYSTEM_PROPERTIES_CONTEXTS_PRE_SPLIT_H
+
+#include "contexts.h"
+#include "prop_area.h"
+#include "prop_info.h"
+#include "property_filename.h"
+
+class ContextsPreSplit : public Contexts {
+ public:
+ virtual ~ContextsPreSplit() override {
+ }
+
+ // We'll never initialize this legacy option as writable, so don't even check the arg.
+ virtual bool Initialize(bool) override {
+ pre_split_prop_area_ = prop_area::map_prop_area(property_filename);
+ return pre_split_prop_area_ != nullptr;
+ }
+
+ virtual prop_area* GetPropAreaForName(const char*) override {
+ return pre_split_prop_area_;
+ }
+
+ virtual prop_area* GetSerialPropArea() override {
+ return pre_split_prop_area_;
+ }
+
+ virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) override {
+ pre_split_prop_area_->foreach (propfn, cookie);
+ }
+
+ // This is a no-op for pre-split properties as there is only one property file and it is
+ // accessible by all domains
+ virtual void ResetAccess() override {
+ }
+
+ virtual void FreeAndUnmap() override {
+ prop_area::unmap_prop_area(&pre_split_prop_area_);
+ }
+
+ private:
+ prop_area* pre_split_prop_area_ = nullptr;
+};
+
+#endif
diff --git a/libc/system_properties/contexts_split.cpp b/libc/system_properties/contexts_split.cpp
new file mode 100644
index 0000000..77f2069
--- /dev/null
+++ b/libc/system_properties/contexts_split.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "contexts_split.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <async_safe/log.h>
+
+#include "context_node.h"
+#include "property_filename.h"
+
+class ContextListNode : public ContextNode {
+ public:
+ ContextListNode(ContextListNode* next, const char* context)
+ : ContextNode(strdup(context)), next(next) {
+ }
+
+ ~ContextListNode() {
+ free(const_cast<char*>(context()));
+ }
+
+ ContextListNode* next;
+};
+
+struct PrefixNode {
+ PrefixNode(struct PrefixNode* next, const char* prefix, ContextListNode* context)
+ : prefix(strdup(prefix)), prefix_len(strlen(prefix)), context(context), next(next) {
+ }
+ ~PrefixNode() {
+ free(prefix);
+ }
+ char* prefix;
+ const size_t prefix_len;
+ ContextListNode* context;
+ PrefixNode* next;
+};
+
+template <typename List, typename... Args>
+static inline void ListAdd(List** list, Args... args) {
+ *list = new List(*list, args...);
+}
+
+static void ListAddAfterLen(PrefixNode** list, const char* prefix, ContextListNode* context) {
+ size_t prefix_len = strlen(prefix);
+
+ auto next_list = list;
+
+ while (*next_list) {
+ if ((*next_list)->prefix_len < prefix_len || (*next_list)->prefix[0] == '*') {
+ ListAdd(next_list, prefix, context);
+ return;
+ }
+ next_list = &(*next_list)->next;
+ }
+ ListAdd(next_list, prefix, context);
+}
+
+template <typename List, typename Func>
+static void ListForEach(List* list, Func func) {
+ while (list) {
+ func(list);
+ list = list->next;
+ }
+}
+
+template <typename List, typename Func>
+static List* ListFind(List* list, Func func) {
+ while (list) {
+ if (func(list)) {
+ return list;
+ }
+ list = list->next;
+ }
+ return nullptr;
+}
+
+template <typename List>
+static void ListFree(List** list) {
+ while (*list) {
+ auto old_list = *list;
+ *list = old_list->next;
+ delete old_list;
+ }
+}
+
+// The below two functions are duplicated from label_support.c in libselinux.
+// TODO: Find a location suitable for these functions such that both libc and
+// libselinux can share a common source file.
+
+// The read_spec_entries and read_spec_entry functions may be used to
+// replace sscanf to read entries from spec files. The file and
+// property services now use these.
+
+// Read an entry from a spec file (e.g. file_contexts)
+static inline int read_spec_entry(char** entry, char** ptr, int* len) {
+ *entry = nullptr;
+ char* tmp_buf = nullptr;
+
+ while (isspace(**ptr) && **ptr != '\0') (*ptr)++;
+
+ tmp_buf = *ptr;
+ *len = 0;
+
+ while (!isspace(**ptr) && **ptr != '\0') {
+ (*ptr)++;
+ (*len)++;
+ }
+
+ if (*len) {
+ *entry = strndup(tmp_buf, *len);
+ if (!*entry) return -1;
+ }
+
+ return 0;
+}
+
+// line_buf - Buffer containing the spec entries .
+// num_args - The number of spec parameter entries to process.
+// ... - A 'char **spec_entry' for each parameter.
+// returns - The number of items processed.
+//
+// This function calls read_spec_entry() to do the actual string processing.
+static int read_spec_entries(char* line_buf, int num_args, ...) {
+ char **spec_entry, *buf_p;
+ int len, rc, items, entry_len = 0;
+ va_list ap;
+
+ len = strlen(line_buf);
+ if (line_buf[len - 1] == '\n')
+ line_buf[len - 1] = '\0';
+ else
+ // Handle case if line not \n terminated by bumping
+ // the len for the check below (as the line is NUL
+ // terminated by getline(3))
+ len++;
+
+ buf_p = line_buf;
+ while (isspace(*buf_p)) buf_p++;
+
+ // Skip comment lines and empty lines.
+ if (*buf_p == '#' || *buf_p == '\0') return 0;
+
+ // Process the spec file entries
+ va_start(ap, num_args);
+
+ items = 0;
+ while (items < num_args) {
+ spec_entry = va_arg(ap, char**);
+
+ if (len - 1 == buf_p - line_buf) {
+ va_end(ap);
+ return items;
+ }
+
+ rc = read_spec_entry(spec_entry, &buf_p, &entry_len);
+ if (rc < 0) {
+ va_end(ap);
+ return rc;
+ }
+ if (entry_len) items++;
+ }
+ va_end(ap);
+ return items;
+}
+
+bool ContextsSplit::MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed) {
+ char filename[PROP_FILENAME_MAX];
+ int len = async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial",
+ property_filename);
+ if (len < 0 || len > PROP_FILENAME_MAX) {
+ serial_prop_area_ = nullptr;
+ return false;
+ }
+
+ if (access_rw) {
+ serial_prop_area_ =
+ prop_area::map_prop_area_rw(filename, "u:object_r:properties_serial:s0", fsetxattr_failed);
+ } else {
+ serial_prop_area_ = prop_area::map_prop_area(filename);
+ }
+ return serial_prop_area_;
+}
+
+bool ContextsSplit::InitializePropertiesFromFile(const char* filename) {
+ FILE* file = fopen(filename, "re");
+ if (!file) {
+ return false;
+ }
+
+ char* buffer = nullptr;
+ size_t line_len;
+ char* prop_prefix = nullptr;
+ char* context = nullptr;
+
+ while (getline(&buffer, &line_len, file) > 0) {
+ int items = read_spec_entries(buffer, 2, &prop_prefix, &context);
+ if (items <= 0) {
+ continue;
+ }
+ if (items == 1) {
+ free(prop_prefix);
+ continue;
+ }
+
+ // init uses ctl.* properties as an IPC mechanism and does not write them
+ // to a property file, therefore we do not need to create property files
+ // to store them.
+ if (!strncmp(prop_prefix, "ctl.", 4)) {
+ free(prop_prefix);
+ free(context);
+ continue;
+ }
+
+ auto old_context = ListFind(
+ contexts_, [context](ContextListNode* l) { return !strcmp(l->context(), context); });
+ if (old_context) {
+ ListAddAfterLen(&prefixes_, prop_prefix, old_context);
+ } else {
+ ListAdd(&contexts_, context);
+ ListAddAfterLen(&prefixes_, prop_prefix, contexts_);
+ }
+ free(prop_prefix);
+ free(context);
+ }
+
+ free(buffer);
+ fclose(file);
+
+ return true;
+}
+
+bool ContextsSplit::InitializeProperties() {
+ // If we do find /property_contexts, then this is being
+ // run as part of the OTA updater on older release that had
+ // /property_contexts - b/34370523
+ if (InitializePropertiesFromFile("/property_contexts")) {
+ return true;
+ }
+
+ // Use property_contexts from /system & /vendor, fall back to those from /
+ if (access("/system/etc/selinux/plat_property_contexts", R_OK) != -1) {
+ if (!InitializePropertiesFromFile("/system/etc/selinux/plat_property_contexts")) {
+ return false;
+ }
+ // Don't check for failure here, so we always have a sane list of properties.
+ // E.g. In case of recovery, the vendor partition will not have mounted and we
+ // still need the system / platform properties to function.
+ InitializePropertiesFromFile("/vendor/etc/selinux/nonplat_property_contexts");
+ } else {
+ if (!InitializePropertiesFromFile("/plat_property_contexts")) {
+ return false;
+ }
+ InitializePropertiesFromFile("/nonplat_property_contexts");
+ }
+
+ return true;
+}
+
+bool ContextsSplit::Initialize(bool writable) {
+ if (!InitializeProperties()) {
+ return false;
+ }
+
+ if (writable) {
+ mkdir(property_filename, S_IRWXU | S_IXGRP | S_IXOTH);
+ bool open_failed = false;
+ bool fsetxattr_failed = false;
+ ListForEach(contexts_, [&fsetxattr_failed, &open_failed](ContextListNode* l) {
+ if (!l->Open(true, &fsetxattr_failed)) {
+ open_failed = true;
+ }
+ });
+ if (open_failed || !MapSerialPropertyArea(true, &fsetxattr_failed)) {
+ FreeAndUnmap();
+ return false;
+ }
+
+ return !fsetxattr_failed;
+ } else {
+ if (!MapSerialPropertyArea(false, nullptr)) {
+ FreeAndUnmap();
+ return false;
+ }
+ }
+ return true;
+}
+
+prop_area* ContextsSplit::GetPropAreaForName(const char* name) {
+ auto entry = ListFind(prefixes_, [name](PrefixNode* l) {
+ return l->prefix[0] == '*' || !strncmp(l->prefix, name, l->prefix_len);
+ });
+ if (!entry) {
+ return nullptr;
+ }
+
+ auto cnode = entry->context;
+ if (!cnode->pa()) {
+ // We explicitly do not check no_access_ in this case because unlike the
+ // case of foreach(), we want to generate an selinux audit for each
+ // non-permitted property access in this function.
+ cnode->Open(false, nullptr);
+ }
+ return cnode->pa();
+}
+
+void ContextsSplit::ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+ ListForEach(contexts_, [propfn, cookie](ContextListNode* l) {
+ if (l->CheckAccessAndOpen()) {
+ l->pa()->foreach (propfn, cookie);
+ }
+ });
+}
+
+void ContextsSplit::ResetAccess() {
+ ListForEach(contexts_, [](ContextListNode* l) { l->ResetAccess(); });
+}
+
+void ContextsSplit::FreeAndUnmap() {
+ ListFree(&prefixes_);
+ ListFree(&contexts_);
+ prop_area::unmap_prop_area(&serial_prop_area_);
+}
diff --git a/libc/system_properties/contexts_split.h b/libc/system_properties/contexts_split.h
new file mode 100644
index 0000000..f98eb44
--- /dev/null
+++ b/libc/system_properties/contexts_split.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
+#define SYSTEM_PROPERTIES_CONTEXTS_SPLIT_H
+
+#include "contexts.h"
+
+struct PrefixNode;
+class ContextListNode;
+
+class ContextsSplit : public Contexts {
+ public:
+ virtual ~ContextsSplit() override {
+ }
+
+ virtual bool Initialize(bool writable) override;
+ virtual prop_area* GetPropAreaForName(const char* name) override;
+ virtual prop_area* GetSerialPropArea() override {
+ return serial_prop_area_;
+ }
+ virtual void ForEach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) override;
+ virtual void ResetAccess() override;
+ virtual void FreeAndUnmap() override;
+
+ private:
+ bool MapSerialPropertyArea(bool access_rw, bool* fsetxattr_failed);
+ bool InitializePropertiesFromFile(const char* filename);
+ bool InitializeProperties();
+
+ PrefixNode* prefixes_ = nullptr;
+ ContextListNode* contexts_ = nullptr;
+ prop_area* serial_prop_area_ = nullptr;
+};
+
+#endif
diff --git a/libc/system_properties/prop_area.cpp b/libc/system_properties/prop_area.cpp
new file mode 100644
index 0000000..e11f292
--- /dev/null
+++ b/libc/system_properties/prop_area.cpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/cdefs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+#include <unistd.h>
+
+#include <new>
+
+#include <async_safe/log.h>
+
+#include "prop_area.h"
+
+constexpr size_t PA_SIZE = 128 * 1024;
+constexpr uint32_t PROP_AREA_MAGIC = 0x504f5250;
+constexpr uint32_t PROP_AREA_VERSION = 0xfc6ed0ab;
+
+size_t prop_area::pa_size_ = 0;
+size_t prop_area::pa_data_size_ = 0;
+
+prop_area* prop_area::map_prop_area_rw(const char* filename, const char* context,
+ bool* fsetxattr_failed) {
+ /* dev is a tmpfs that we can use to carve a shared workspace
+ * out of, so let's do that...
+ */
+ const int fd = open(filename, O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
+
+ if (fd < 0) {
+ if (errno == EACCES) {
+ /* for consistency with the case where the process has already
+ * mapped the page in and segfaults when trying to write to it
+ */
+ abort();
+ }
+ return nullptr;
+ }
+
+ if (context) {
+ if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "fsetxattr failed to set context (%s) for \"%s\"", context, filename);
+ /*
+ * fsetxattr() will fail during system properties tests due to selinux policy.
+ * We do not want to create a custom policy for the tester, so we will continue in
+ * this function but set a flag that an error has occurred.
+ * Init, which is the only daemon that should ever call this function will abort
+ * when this error occurs.
+ * Otherwise, the tester will ignore it and continue, albeit without any selinux
+ * property separation.
+ */
+ if (fsetxattr_failed) {
+ *fsetxattr_failed = true;
+ }
+ }
+ }
+
+ if (ftruncate(fd, PA_SIZE) < 0) {
+ close(fd);
+ return nullptr;
+ }
+
+ pa_size_ = PA_SIZE;
+ pa_data_size_ = pa_size_ - sizeof(prop_area);
+
+ void* const memory_area = mmap(nullptr, pa_size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (memory_area == MAP_FAILED) {
+ close(fd);
+ return nullptr;
+ }
+
+ prop_area* pa = new (memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
+
+ close(fd);
+ return pa;
+}
+
+prop_area* prop_area::map_fd_ro(const int fd) {
+ struct stat fd_stat;
+ if (fstat(fd, &fd_stat) < 0) {
+ return nullptr;
+ }
+
+ if ((fd_stat.st_uid != 0) || (fd_stat.st_gid != 0) ||
+ ((fd_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0) ||
+ (fd_stat.st_size < static_cast<off_t>(sizeof(prop_area)))) {
+ return nullptr;
+ }
+
+ pa_size_ = fd_stat.st_size;
+ pa_data_size_ = pa_size_ - sizeof(prop_area);
+
+ void* const map_result = mmap(nullptr, pa_size_, PROT_READ, MAP_SHARED, fd, 0);
+ if (map_result == MAP_FAILED) {
+ return nullptr;
+ }
+
+ prop_area* pa = reinterpret_cast<prop_area*>(map_result);
+ if ((pa->magic() != PROP_AREA_MAGIC) || (pa->version() != PROP_AREA_VERSION)) {
+ munmap(pa, pa_size_);
+ return nullptr;
+ }
+
+ return pa;
+}
+
+prop_area* prop_area::map_prop_area(const char* filename) {
+ int fd = open(filename, O_CLOEXEC | O_NOFOLLOW | O_RDONLY);
+ if (fd == -1) return nullptr;
+
+ prop_area* map_result = map_fd_ro(fd);
+ close(fd);
+
+ return map_result;
+}
+
+void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
+ const size_t aligned = __BIONIC_ALIGN(size, sizeof(uint_least32_t));
+ if (bytes_used_ + aligned > pa_data_size_) {
+ return nullptr;
+ }
+
+ *off = bytes_used_;
+ bytes_used_ += aligned;
+ return data_ + *off;
+}
+
+prop_bt* prop_area::new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off) {
+ uint_least32_t new_offset;
+ void* const p = allocate_obj(sizeof(prop_bt) + namelen + 1, &new_offset);
+ if (p != nullptr) {
+ prop_bt* bt = new (p) prop_bt(name, namelen);
+ *off = new_offset;
+ return bt;
+ }
+
+ return nullptr;
+}
+
+prop_info* prop_area::new_prop_info(const char* name, uint32_t namelen, const char* value,
+ uint32_t valuelen, uint_least32_t* const off) {
+ uint_least32_t new_offset;
+ void* const p = allocate_obj(sizeof(prop_info) + namelen + 1, &new_offset);
+ if (p == nullptr) return nullptr;
+
+ prop_info* info;
+ if (valuelen >= PROP_VALUE_MAX) {
+ uint32_t long_value_offset = 0;
+ char* long_location = reinterpret_cast<char*>(allocate_obj(valuelen + 1, &long_value_offset));
+ if (!long_location) return nullptr;
+
+ memcpy(long_location, value, valuelen);
+ long_location[valuelen] = '\0';
+
+ // Both new_offset and long_value_offset are offsets based off of data_, however prop_info
+ // does not know what data_ is, so we change this offset to be an offset from the prop_info
+ // pointer that contains it.
+ long_value_offset -= new_offset;
+
+ info = new (p) prop_info(name, namelen, long_value_offset);
+ } else {
+ info = new (p) prop_info(name, namelen, value, valuelen);
+ }
+ *off = new_offset;
+ return info;
+}
+
+void* prop_area::to_prop_obj(uint_least32_t off) {
+ if (off > pa_data_size_) return nullptr;
+
+ return (data_ + off);
+}
+
+inline prop_bt* prop_area::to_prop_bt(atomic_uint_least32_t* off_p) {
+ uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
+ return reinterpret_cast<prop_bt*>(to_prop_obj(off));
+}
+
+inline prop_info* prop_area::to_prop_info(atomic_uint_least32_t* off_p) {
+ uint_least32_t off = atomic_load_explicit(off_p, memory_order_consume);
+ return reinterpret_cast<prop_info*>(to_prop_obj(off));
+}
+
+inline prop_bt* prop_area::root_node() {
+ return reinterpret_cast<prop_bt*>(to_prop_obj(0));
+}
+
+static int cmp_prop_name(const char* one, uint32_t one_len, const char* two, uint32_t two_len) {
+ if (one_len < two_len)
+ return -1;
+ else if (one_len > two_len)
+ return 1;
+ else
+ return strncmp(one, two, one_len);
+}
+
+prop_bt* prop_area::find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen,
+ bool alloc_if_needed) {
+ prop_bt* current = bt;
+ while (true) {
+ if (!current) {
+ return nullptr;
+ }
+
+ const int ret = cmp_prop_name(name, namelen, current->name, current->namelen);
+ if (ret == 0) {
+ return current;
+ }
+
+ if (ret < 0) {
+ uint_least32_t left_offset = atomic_load_explicit(¤t->left, memory_order_relaxed);
+ if (left_offset != 0) {
+ current = to_prop_bt(¤t->left);
+ } else {
+ if (!alloc_if_needed) {
+ return nullptr;
+ }
+
+ uint_least32_t new_offset;
+ prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
+ if (new_bt) {
+ atomic_store_explicit(¤t->left, new_offset, memory_order_release);
+ }
+ return new_bt;
+ }
+ } else {
+ uint_least32_t right_offset = atomic_load_explicit(¤t->right, memory_order_relaxed);
+ if (right_offset != 0) {
+ current = to_prop_bt(¤t->right);
+ } else {
+ if (!alloc_if_needed) {
+ return nullptr;
+ }
+
+ uint_least32_t new_offset;
+ prop_bt* new_bt = new_prop_bt(name, namelen, &new_offset);
+ if (new_bt) {
+ atomic_store_explicit(¤t->right, new_offset, memory_order_release);
+ }
+ return new_bt;
+ }
+ }
+ }
+}
+
+const prop_info* prop_area::find_property(prop_bt* const trie, const char* name, uint32_t namelen,
+ const char* value, uint32_t valuelen,
+ bool alloc_if_needed) {
+ if (!trie) return nullptr;
+
+ const char* remaining_name = name;
+ prop_bt* current = trie;
+ while (true) {
+ const char* sep = strchr(remaining_name, '.');
+ const bool want_subtree = (sep != nullptr);
+ const uint32_t substr_size = (want_subtree) ? sep - remaining_name : strlen(remaining_name);
+
+ if (!substr_size) {
+ return nullptr;
+ }
+
+ prop_bt* root = nullptr;
+ uint_least32_t children_offset = atomic_load_explicit(¤t->children, memory_order_relaxed);
+ if (children_offset != 0) {
+ root = to_prop_bt(¤t->children);
+ } else if (alloc_if_needed) {
+ uint_least32_t new_offset;
+ root = new_prop_bt(remaining_name, substr_size, &new_offset);
+ if (root) {
+ atomic_store_explicit(¤t->children, new_offset, memory_order_release);
+ }
+ }
+
+ if (!root) {
+ return nullptr;
+ }
+
+ current = find_prop_bt(root, remaining_name, substr_size, alloc_if_needed);
+ if (!current) {
+ return nullptr;
+ }
+
+ if (!want_subtree) break;
+
+ remaining_name = sep + 1;
+ }
+
+ uint_least32_t prop_offset = atomic_load_explicit(¤t->prop, memory_order_relaxed);
+ if (prop_offset != 0) {
+ return to_prop_info(¤t->prop);
+ } else if (alloc_if_needed) {
+ uint_least32_t new_offset;
+ prop_info* new_info = new_prop_info(name, namelen, value, valuelen, &new_offset);
+ if (new_info) {
+ atomic_store_explicit(¤t->prop, new_offset, memory_order_release);
+ }
+
+ return new_info;
+ } else {
+ return nullptr;
+ }
+}
+
+bool prop_area::foreach_property(prop_bt* const trie,
+ void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+ if (!trie) return false;
+
+ uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed);
+ if (left_offset != 0) {
+ const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie);
+ if (err < 0) return false;
+ }
+ uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed);
+ if (prop_offset != 0) {
+ prop_info* info = to_prop_info(&trie->prop);
+ if (!info) return false;
+ propfn(info, cookie);
+ }
+ uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed);
+ if (children_offset != 0) {
+ const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie);
+ if (err < 0) return false;
+ }
+ uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed);
+ if (right_offset != 0) {
+ const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie);
+ if (err < 0) return false;
+ }
+
+ return true;
+}
+
+const prop_info* prop_area::find(const char* name) {
+ return find_property(root_node(), name, strlen(name), nullptr, 0, false);
+}
+
+bool prop_area::add(const char* name, unsigned int namelen, const char* value,
+ unsigned int valuelen) {
+ return find_property(root_node(), name, namelen, value, valuelen, true);
+}
+
+bool prop_area::foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+ return foreach_property(root_node(), propfn, cookie);
+}
diff --git a/libc/system_properties/prop_area.h b/libc/system_properties/prop_area.h
new file mode 100644
index 0000000..10c1adb
--- /dev/null
+++ b/libc/system_properties/prop_area.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdatomic.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "private/bionic_macros.h"
+
+#include "prop_info.h"
+
+#ifndef SYSTEM_PROPERTIES_PROP_AREA_H
+#define SYSTEM_PROPERTIES_PROP_AREA_H
+
+// Properties are stored in a hybrid trie/binary tree structure.
+// Each property's name is delimited at '.' characters, and the tokens are put
+// into a trie structure. Siblings at each level of the trie are stored in a
+// binary tree. For instance, "ro.secure"="1" could be stored as follows:
+//
+// +-----+ children +----+ children +--------+
+// | |-------------->| ro |-------------->| secure |
+// +-----+ +----+ +--------+
+// / \ / |
+// left / \ right left / | prop +===========+
+// v v v +-------->| ro.secure |
+// +-----+ +-----+ +-----+ +-----------+
+// | net | | sys | | com | | 1 |
+// +-----+ +-----+ +-----+ +===========+
+
+// Represents a node in the trie.
+struct prop_bt {
+ uint32_t namelen;
+
+ // The property trie is updated only by the init process (single threaded) which provides
+ // property service. And it can be read by multiple threads at the same time.
+ // As the property trie is not protected by locks, we use atomic_uint_least32_t types for the
+ // left, right, children "pointers" in the trie node. To make sure readers who see the
+ // change of "pointers" can also notice the change of prop_bt structure contents pointed by
+ // the "pointers", we always use release-consume ordering pair when accessing these "pointers".
+
+ // prop "points" to prop_info structure if there is a propery associated with the trie node.
+ // Its situation is similar to the left, right, children "pointers". So we use
+ // atomic_uint_least32_t and release-consume ordering to protect it as well.
+
+ // We should also avoid rereading these fields redundantly, since not
+ // all processor implementations ensure that multiple loads from the
+ // same field are carried out in the right order.
+ atomic_uint_least32_t prop;
+
+ atomic_uint_least32_t left;
+ atomic_uint_least32_t right;
+
+ atomic_uint_least32_t children;
+
+ char name[0];
+
+ prop_bt(const char* name, const uint32_t name_length) {
+ this->namelen = name_length;
+ memcpy(this->name, name, name_length);
+ this->name[name_length] = '\0';
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(prop_bt);
+};
+
+class prop_area {
+ public:
+ static prop_area* map_prop_area_rw(const char* filename, const char* context,
+ bool* fsetxattr_failed);
+ static prop_area* map_prop_area(const char* filename);
+ static void unmap_prop_area(prop_area** pa) {
+ if (*pa) {
+ munmap(*pa, pa_size_);
+ *pa = nullptr;
+ }
+ }
+
+ prop_area(const uint32_t magic, const uint32_t version) : magic_(magic), version_(version) {
+ atomic_init(&serial_, 0);
+ memset(reserved_, 0, sizeof(reserved_));
+ // Allocate enough space for the root node.
+ bytes_used_ = sizeof(prop_bt);
+ }
+
+ const prop_info* find(const char* name);
+ bool add(const char* name, unsigned int namelen, const char* value, unsigned int valuelen);
+
+ bool foreach (void (*propfn)(const prop_info* pi, void* cookie), void* cookie);
+
+ atomic_uint_least32_t* serial() {
+ return &serial_;
+ }
+ uint32_t magic() const {
+ return magic_;
+ }
+ uint32_t version() const {
+ return version_;
+ }
+
+ private:
+ static prop_area* map_fd_ro(const int fd);
+
+ void* allocate_obj(const size_t size, uint_least32_t* const off);
+ prop_bt* new_prop_bt(const char* name, uint32_t namelen, uint_least32_t* const off);
+ prop_info* new_prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen,
+ uint_least32_t* const off);
+ void* to_prop_obj(uint_least32_t off);
+ prop_bt* to_prop_bt(atomic_uint_least32_t* off_p);
+ prop_info* to_prop_info(atomic_uint_least32_t* off_p);
+
+ prop_bt* root_node();
+
+ prop_bt* find_prop_bt(prop_bt* const bt, const char* name, uint32_t namelen, bool alloc_if_needed);
+
+ const prop_info* find_property(prop_bt* const trie, const char* name, uint32_t namelen,
+ const char* value, uint32_t valuelen, bool alloc_if_needed);
+
+ bool foreach_property(prop_bt* const trie, void (*propfn)(const prop_info* pi, void* cookie),
+ void* cookie);
+
+ // The original design doesn't include pa_size or pa_data_size in the prop_area struct itself.
+ // Since we'll need to be backwards compatible with that design, we don't gain much by adding it
+ // now, especially since we don't have any plans to make different property areas different sizes,
+ // and thus we share these two variables among all instances.
+ static size_t pa_size_;
+ static size_t pa_data_size_;
+
+ uint32_t bytes_used_;
+ atomic_uint_least32_t serial_;
+ uint32_t magic_;
+ uint32_t version_;
+ uint32_t reserved_[28];
+ char data_[0];
+
+ DISALLOW_COPY_AND_ASSIGN(prop_area);
+};
+
+#endif
diff --git a/libc/system_properties/prop_info.cpp b/libc/system_properties/prop_info.cpp
new file mode 100644
index 0000000..5123f92
--- /dev/null
+++ b/libc/system_properties/prop_info.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "prop_info.h"
+
+#include <string.h>
+
+constexpr static const char kLongLegacyError[] =
+ "Must use __system_property_read_callback() to read";
+static_assert(sizeof(kLongLegacyError) < prop_info::kLongLegacyErrorBufferSize,
+ "Error message for long properties read by legacy libc must fit within 56 chars");
+
+prop_info::prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen) {
+ memcpy(this->name, name, namelen);
+ this->name[namelen] = '\0';
+ atomic_init(&this->serial, valuelen << 24);
+ memcpy(this->value, value, valuelen);
+ this->value[valuelen] = '\0';
+}
+
+prop_info::prop_info(const char* name, uint32_t namelen, uint32_t long_offset) {
+ memcpy(this->name, name, namelen);
+ this->name[namelen] = '\0';
+
+ auto error_value_len = sizeof(kLongLegacyError) - 1;
+ atomic_init(&this->serial, error_value_len << 24 | kLongFlag);
+ memcpy(this->long_property.error_message, kLongLegacyError, sizeof(kLongLegacyError));
+
+ this->long_property.offset = long_offset;
+}
diff --git a/libc/system_properties/prop_info.h b/libc/system_properties/prop_info.h
new file mode 100644
index 0000000..99bcaaf
--- /dev/null
+++ b/libc/system_properties/prop_info.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdatomic.h>
+#include <stdint.h>
+#include <sys/system_properties.h>
+
+#include "private/bionic_macros.h"
+
+#ifndef SYSTEM_PROPERTIES_PROP_INFO_H
+#define SYSTEM_PROPERTIES_PROP_INFO_H
+
+// The C11 standard doesn't allow atomic loads from const fields,
+// though C++11 does. Fudge it until standards get straightened out.
+static inline uint_least32_t load_const_atomic(const atomic_uint_least32_t* s, memory_order mo) {
+ atomic_uint_least32_t* non_const_s = const_cast<atomic_uint_least32_t*>(s);
+ return atomic_load_explicit(non_const_s, mo);
+}
+
+struct prop_info {
+ // Read only properties will not set anything but the bottom most bit of serial and the top byte.
+ // We borrow the 2nd from the top byte for extra flags, and use the bottom most bit of that for
+ // our first user, kLongFlag.
+ constexpr static uint32_t kLongFlag = 1 << 16;
+
+ // The error message fits in part of a union with the previous 92 char property value so there
+ // must be room left over after the error message for the offset to the new longer property value
+ // and future expansion fields if needed. Note that this value cannot ever increase. The offset
+ // to the new longer property value appears immediately after it, so an increase of this size will
+ // break compatibility.
+ constexpr static size_t kLongLegacyErrorBufferSize = 56;
+
+ public:
+ atomic_uint_least32_t serial;
+ // we need to keep this buffer around because the property
+ // value can be modified whereas name is constant.
+ union {
+ char value[PROP_VALUE_MAX];
+ struct {
+ char error_message[kLongLegacyErrorBufferSize];
+ uint32_t offset;
+ } long_property;
+ };
+ char name[0];
+
+ bool is_long() const {
+ return (load_const_atomic(&serial, memory_order_relaxed) & kLongFlag) != 0;
+ }
+
+ const char* long_value() const {
+ // We can't store pointers here since this is shared memory that will have different absolute
+ // pointers in different processes. We don't have data_ from prop_area, but since we know
+ // `this` is data_ + some offset and long_value is data_ + some other offset, we calculate the
+ // offset from `this` to long_value and store it as long_property.offset.
+ return reinterpret_cast<const char*>(this) + long_property.offset;
+ }
+
+ prop_info(const char* name, uint32_t namelen, const char* value, uint32_t valuelen);
+ prop_info(const char* name, uint32_t namelen, uint32_t long_offset);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
+};
+
+static_assert(sizeof(prop_info) == 96, "sizeof struct prop_info must be 96 bytes");
+
+#endif
diff --git a/libc/system_properties/property_filename.h b/libc/system_properties/property_filename.h
new file mode 100644
index 0000000..0f7bcf7
--- /dev/null
+++ b/libc/system_properties/property_filename.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef SYSTEM_PROPERTIES_PROPERTY_FILENAME_H
+#define SYSTEM_PROPERTIES_PROPERTY_FILENAME_H
+
+// These are globals set by __system_property_set_filename().
+// There isn't huge benefit in refactoring them, so they're alone in this header.
+constexpr int PROP_FILENAME_MAX = 1024;
+extern char property_filename[PROP_FILENAME_MAX];
+
+#endif
diff --git a/libc/system_properties/system_properties.cpp b/libc/system_properties/system_properties.cpp
new file mode 100644
index 0000000..3f6601d
--- /dev/null
+++ b/libc/system_properties/system_properties.cpp
@@ -0,0 +1,675 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <stdatomic.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+#include <sys/system_properties.h>
+
+#include <async_safe/log.h>
+
+#include "private/ErrnoRestorer.h"
+#include "private/bionic_defs.h"
+#include "private/bionic_futex.h"
+#include "private/bionic_macros.h"
+#include "private/bionic_sdk_version.h"
+
+#include "context_node.h"
+#include "contexts.h"
+#include "contexts_pre_split.h"
+#include "contexts_split.h"
+#include "prop_area.h"
+#include "prop_info.h"
+#include "property_filename.h"
+
+// We don't want to use new or malloc in properties (b/31659220), and since these classes are
+// small enough and don't have non-trivial constructors, it's easier to just statically declare
+// them than anything else.
+static ContextsSplit contexts_split;
+static ContextsPreSplit contexts_pre_split;
+static Contexts* contexts = nullptr;
+
+#define SERIAL_DIRTY(serial) ((serial)&1)
+#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
+
+static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME;
+static const char* kServiceVersionPropertyName = "ro.property_service.version";
+
+// This is public because it was exposed in the NDK. As of 2017-01, ~60 apps reference this symbol.
+// It is set to nullptr and never modified.
+__BIONIC_WEAK_VARIABLE_FOR_NATIVE_BRIDGE
+prop_area* __system_property_area__ = nullptr;
+
+char property_filename[PROP_FILENAME_MAX] = PROP_FILENAME;
+
+class PropertyServiceConnection {
+ public:
+ PropertyServiceConnection() : last_error_(0) {
+ socket_ = ::socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (socket_ == -1) {
+ last_error_ = errno;
+ return;
+ }
+
+ const size_t namelen = strlen(property_service_socket);
+ sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ strlcpy(addr.sun_path, property_service_socket, sizeof(addr.sun_path));
+ addr.sun_family = AF_LOCAL;
+ socklen_t alen = namelen + offsetof(sockaddr_un, sun_path) + 1;
+
+ if (TEMP_FAILURE_RETRY(connect(socket_, reinterpret_cast<sockaddr*>(&addr), alen)) == -1) {
+ last_error_ = errno;
+ close(socket_);
+ socket_ = -1;
+ }
+ }
+
+ bool IsValid() {
+ return socket_ != -1;
+ }
+
+ int GetLastError() {
+ return last_error_;
+ }
+
+ bool RecvInt32(int32_t* value) {
+ int result = TEMP_FAILURE_RETRY(recv(socket_, value, sizeof(*value), MSG_WAITALL));
+ return CheckSendRecvResult(result, sizeof(*value));
+ }
+
+ int socket() {
+ return socket_;
+ }
+
+ ~PropertyServiceConnection() {
+ if (socket_ != -1) {
+ close(socket_);
+ }
+ }
+
+ private:
+ bool CheckSendRecvResult(int result, int expected_len) {
+ if (result == -1) {
+ last_error_ = errno;
+ } else if (result != expected_len) {
+ last_error_ = -1;
+ } else {
+ last_error_ = 0;
+ }
+
+ return last_error_ == 0;
+ }
+
+ int socket_;
+ int last_error_;
+
+ friend class SocketWriter;
+};
+
+class SocketWriter {
+ public:
+ explicit SocketWriter(PropertyServiceConnection* connection)
+ : connection_(connection), iov_index_(0), uint_buf_index_(0) {
+ }
+
+ SocketWriter& WriteUint32(uint32_t value) {
+ CHECK(uint_buf_index_ < kUintBufSize);
+ CHECK(iov_index_ < kIovSize);
+ uint32_t* ptr = uint_buf_ + uint_buf_index_;
+ uint_buf_[uint_buf_index_++] = value;
+ iov_[iov_index_].iov_base = ptr;
+ iov_[iov_index_].iov_len = sizeof(*ptr);
+ ++iov_index_;
+ return *this;
+ }
+
+ SocketWriter& WriteString(const char* value) {
+ uint32_t valuelen = strlen(value);
+ WriteUint32(valuelen);
+ if (valuelen == 0) {
+ return *this;
+ }
+
+ CHECK(iov_index_ < kIovSize);
+ iov_[iov_index_].iov_base = const_cast<char*>(value);
+ iov_[iov_index_].iov_len = valuelen;
+ ++iov_index_;
+
+ return *this;
+ }
+
+ bool Send() {
+ if (!connection_->IsValid()) {
+ return false;
+ }
+
+ if (writev(connection_->socket(), iov_, iov_index_) == -1) {
+ connection_->last_error_ = errno;
+ return false;
+ }
+
+ iov_index_ = uint_buf_index_ = 0;
+ return true;
+ }
+
+ private:
+ static constexpr size_t kUintBufSize = 8;
+ static constexpr size_t kIovSize = 8;
+
+ PropertyServiceConnection* connection_;
+ iovec iov_[kIovSize];
+ size_t iov_index_;
+ uint32_t uint_buf_[kUintBufSize];
+ size_t uint_buf_index_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
+};
+
+struct prop_msg {
+ unsigned cmd;
+ char name[PROP_NAME_MAX];
+ char value[PROP_VALUE_MAX];
+};
+
+static int send_prop_msg(const prop_msg* msg) {
+ PropertyServiceConnection connection;
+ if (!connection.IsValid()) {
+ return connection.GetLastError();
+ }
+
+ int result = -1;
+ int s = connection.socket();
+
+ const int num_bytes = TEMP_FAILURE_RETRY(send(s, msg, sizeof(prop_msg), 0));
+ if (num_bytes == sizeof(prop_msg)) {
+ // We successfully wrote to the property server but now we
+ // wait for the property server to finish its work. It
+ // acknowledges its completion by closing the socket so we
+ // poll here (on nothing), waiting for the socket to close.
+ // If you 'adb shell setprop foo bar' you'll see the POLLHUP
+ // once the socket closes. Out of paranoia we cap our poll
+ // at 250 ms.
+ pollfd pollfds[1];
+ pollfds[0].fd = s;
+ pollfds[0].events = 0;
+ const int poll_result = TEMP_FAILURE_RETRY(poll(pollfds, 1, 250 /* ms */));
+ if (poll_result == 1 && (pollfds[0].revents & POLLHUP) != 0) {
+ result = 0;
+ } else {
+ // Ignore the timeout and treat it like a success anyway.
+ // The init process is single-threaded and its property
+ // service is sometimes slow to respond (perhaps it's off
+ // starting a child process or something) and thus this
+ // times out and the caller thinks it failed, even though
+ // it's still getting around to it. So we fake it here,
+ // mostly for ctl.* properties, but we do try and wait 250
+ // ms so callers who do read-after-write can reliably see
+ // what they've written. Most of the time.
+ // TODO: fix the system properties design.
+ async_safe_format_log(ANDROID_LOG_WARN, "libc",
+ "Property service has timed out while trying to set \"%s\" to \"%s\"",
+ msg->name, msg->value);
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+static bool is_dir(const char* pathname) {
+ struct stat info;
+ if (stat(pathname, &info) == -1) {
+ return false;
+ }
+ return S_ISDIR(info.st_mode);
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_properties_init() {
+ // This is called from __libc_init_common, and should leave errno at 0 (http://b/37248982).
+ ErrnoRestorer errno_restorer;
+
+ if (contexts != nullptr) {
+ contexts->ResetAccess();
+ return 0;
+ }
+ contexts = nullptr;
+ if (is_dir(property_filename)) {
+ if (!contexts_split.Initialize(false)) {
+ return -1;
+ }
+ contexts = &contexts_split;
+ } else {
+ if (!contexts_pre_split.Initialize(false)) {
+ return -1;
+ }
+ contexts = &contexts_pre_split;
+ }
+ return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_set_filename(const char* filename) {
+ size_t len = strlen(filename);
+ if (len >= sizeof(property_filename)) return -1;
+
+ strcpy(property_filename, filename);
+ return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_area_init() {
+ if (contexts != nullptr) {
+ contexts->FreeAndUnmap();
+ }
+ // We set this unconditionally as we want tests to continue on regardless of if this failed
+ // and property_service will abort on an error condition, so no harm done.
+ contexts = &contexts_split;
+ if (!contexts_split.Initialize(true)) {
+ return -1;
+ }
+ return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_area_serial() {
+ if (contexts == nullptr) {
+ return -1;
+ }
+
+ prop_area* pa = contexts->GetSerialPropArea();
+ if (!pa) {
+ return -1;
+ }
+
+ // Make sure this read fulfilled before __system_property_serial
+ return atomic_load_explicit(pa->serial(), memory_order_acquire);
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+const prop_info* __system_property_find(const char* name) {
+ if (contexts == nullptr) {
+ return nullptr;
+ }
+
+ prop_area* pa = contexts->GetPropAreaForName(name);
+ if (!pa) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name);
+ return nullptr;
+ }
+
+ return pa->find(name);
+}
+
+static bool is_read_only(const char* name) {
+ return strncmp(name, "ro.", 3) == 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_read(const prop_info* pi, char* name, char* value) {
+ while (true) {
+ uint32_t serial = __system_property_serial(pi); // acquire semantics
+ size_t len = SERIAL_VALUE_LEN(serial);
+ memcpy(value, pi->value, len + 1);
+ // TODO: Fix the synchronization scheme here.
+ // There is no fully supported way to implement this kind
+ // of synchronization in C++11, since the memcpy races with
+ // updates to pi, and the data being accessed is not atomic.
+ // The following fence is unintuitive, but would be the
+ // correct one if memcpy used memory_order_relaxed atomic accesses.
+ // In practice it seems unlikely that the generated code would
+ // would be any different, so this should be OK.
+ atomic_thread_fence(memory_order_acquire);
+ if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
+ if (name != nullptr) {
+ size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX);
+ if (namelen >= PROP_NAME_MAX) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+ "The property name length for \"%s\" is >= %d;"
+ " please use __system_property_read_callback"
+ " to read this property. (the name is truncated to \"%s\")",
+ pi->name, PROP_NAME_MAX - 1, name);
+ }
+ }
+ if (is_read_only(pi->name) && pi->is_long()) {
+ async_safe_format_log(
+ ANDROID_LOG_ERROR, "libc",
+ "The property \"%s\" has a value with length %zu that is too large for"
+ " __system_property_get()/__system_property_read(); use"
+ " __system_property_read_callback() instead.",
+ pi->name, strlen(pi->long_value()));
+ }
+ return len;
+ }
+ }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+void __system_property_read_callback(const prop_info* pi,
+ void (*callback)(void* cookie, const char* name,
+ const char* value, uint32_t serial),
+ void* cookie) {
+ // Read only properties don't need to copy the value to a temporary buffer, since it can never
+ // change.
+ if (is_read_only(pi->name)) {
+ uint32_t serial = __system_property_serial(pi);
+ if (pi->is_long()) {
+ callback(cookie, pi->name, pi->long_value(), serial);
+ } else {
+ callback(cookie, pi->name, pi->value, serial);
+ }
+ return;
+ }
+
+ while (true) {
+ uint32_t serial = __system_property_serial(pi); // acquire semantics
+ size_t len = SERIAL_VALUE_LEN(serial);
+ char value_buf[len + 1];
+
+ memcpy(value_buf, pi->value, len);
+ value_buf[len] = '\0';
+
+ // TODO: see todo in __system_property_read function
+ atomic_thread_fence(memory_order_acquire);
+ if (serial == load_const_atomic(&(pi->serial), memory_order_relaxed)) {
+ callback(cookie, pi->name, value_buf, serial);
+ return;
+ }
+ }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_get(const char* name, char* value) {
+ const prop_info* pi = __system_property_find(name);
+
+ if (pi != 0) {
+ return __system_property_read(pi, nullptr, value);
+ } else {
+ value[0] = 0;
+ return 0;
+ }
+}
+
+static constexpr uint32_t kProtocolVersion1 = 1;
+static constexpr uint32_t kProtocolVersion2 = 2; // current
+
+static atomic_uint_least32_t g_propservice_protocol_version = 0;
+
+static void detect_protocol_version() {
+ char value[PROP_VALUE_MAX];
+ if (__system_property_get(kServiceVersionPropertyName, value) == 0) {
+ g_propservice_protocol_version = kProtocolVersion1;
+ async_safe_format_log(ANDROID_LOG_WARN, "libc",
+ "Using old property service protocol (\"%s\" is not set)",
+ kServiceVersionPropertyName);
+ } else {
+ uint32_t version = static_cast<uint32_t>(atoll(value));
+ if (version >= kProtocolVersion2) {
+ g_propservice_protocol_version = kProtocolVersion2;
+ } else {
+ async_safe_format_log(ANDROID_LOG_WARN, "libc",
+ "Using old property service protocol (\"%s\"=\"%s\")",
+ kServiceVersionPropertyName, value);
+ g_propservice_protocol_version = kProtocolVersion1;
+ }
+ }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_set(const char* key, const char* value) {
+ if (key == nullptr) return -1;
+ if (value == nullptr) value = "";
+
+ if (g_propservice_protocol_version == 0) {
+ detect_protocol_version();
+ }
+
+ if (g_propservice_protocol_version == kProtocolVersion1) {
+ // Old protocol does not support long names or values
+ if (strlen(key) >= PROP_NAME_MAX) return -1;
+ if (strlen(value) >= PROP_VALUE_MAX) return -1;
+
+ prop_msg msg;
+ memset(&msg, 0, sizeof msg);
+ msg.cmd = PROP_MSG_SETPROP;
+ strlcpy(msg.name, key, sizeof msg.name);
+ strlcpy(msg.value, value, sizeof msg.value);
+
+ return send_prop_msg(&msg);
+ } else {
+ // New protocol only allows long values for ro. properties only.
+ if (strlen(value) >= PROP_VALUE_MAX && !is_read_only(key)) return -1;
+ // Use proper protocol
+ PropertyServiceConnection connection;
+ if (!connection.IsValid()) {
+ errno = connection.GetLastError();
+ async_safe_format_log(
+ ANDROID_LOG_WARN, "libc",
+ "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", key, value,
+ errno, strerror(errno));
+ return -1;
+ }
+
+ SocketWriter writer(&connection);
+ if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) {
+ errno = connection.GetLastError();
+ async_safe_format_log(ANDROID_LOG_WARN, "libc",
+ "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)",
+ key, value, errno, strerror(errno));
+ return -1;
+ }
+
+ int result = -1;
+ if (!connection.RecvInt32(&result)) {
+ errno = connection.GetLastError();
+ async_safe_format_log(ANDROID_LOG_WARN, "libc",
+ "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)",
+ key, value, errno, strerror(errno));
+ return -1;
+ }
+
+ 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);
+ return -1;
+ }
+
+ return 0;
+ }
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_update(prop_info* pi, const char* value, unsigned int len) {
+ if (len >= PROP_VALUE_MAX) {
+ return -1;
+ }
+
+ if (contexts == nullptr) {
+ return -1;
+ }
+
+ prop_area* pa = contexts->GetSerialPropArea();
+ if (!pa) {
+ return -1;
+ }
+
+ uint32_t serial = atomic_load_explicit(&pi->serial, memory_order_relaxed);
+ serial |= 1;
+ atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);
+ // The memcpy call here also races. Again pretend it
+ // used memory_order_relaxed atomics, and use the analogous
+ // counterintuitive fence.
+ atomic_thread_fence(memory_order_release);
+ strlcpy(pi->value, value, len + 1);
+
+ atomic_store_explicit(&pi->serial, (len << 24) | ((serial + 1) & 0xffffff), memory_order_release);
+ __futex_wake(&pi->serial, INT32_MAX);
+
+ atomic_store_explicit(pa->serial(), atomic_load_explicit(pa->serial(), memory_order_relaxed) + 1,
+ memory_order_release);
+ __futex_wake(pa->serial(), INT32_MAX);
+
+ return 0;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_add(const char* name, unsigned int namelen, const char* value,
+ unsigned int valuelen) {
+ if (valuelen >= PROP_VALUE_MAX && !is_read_only(name)) {
+ return -1;
+ }
+
+ if (namelen < 1) {
+ return -1;
+ }
+
+ if (contexts == nullptr) {
+ return -1;
+ }
+
+ prop_area* serial_pa = contexts->GetSerialPropArea();
+ if (serial_pa == nullptr) {
+ return -1;
+ }
+
+ prop_area* pa = contexts->GetPropAreaForName(name);
+ if (!pa) {
+ async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name);
+ return -1;
+ }
+
+ bool ret = pa->add(name, namelen, value, valuelen);
+ if (!ret) {
+ return -1;
+ }
+
+ // There is only a single mutator, but we want to make sure that
+ // updates are visible to a reader waiting for the update.
+ atomic_store_explicit(serial_pa->serial(),
+ atomic_load_explicit(serial_pa->serial(), memory_order_relaxed) + 1,
+ memory_order_release);
+ __futex_wake(serial_pa->serial(), INT32_MAX);
+ return 0;
+}
+
+// Wait for non-locked serial, and retrieve it with acquire semantics.
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_serial(const prop_info* pi) {
+ uint32_t serial = load_const_atomic(&pi->serial, memory_order_acquire);
+ while (SERIAL_DIRTY(serial)) {
+ __futex_wait(const_cast<_Atomic(uint_least32_t)*>(&pi->serial), serial, nullptr);
+ serial = load_const_atomic(&pi->serial, memory_order_acquire);
+ }
+ return serial;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+uint32_t __system_property_wait_any(uint32_t old_serial) {
+ uint32_t new_serial;
+ __system_property_wait(nullptr, old_serial, &new_serial, nullptr);
+ return new_serial;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+bool __system_property_wait(const prop_info* pi, uint32_t old_serial, uint32_t* new_serial_ptr,
+ const timespec* relative_timeout) {
+ // Are we waiting on the global serial or a specific serial?
+ atomic_uint_least32_t* serial_ptr;
+ if (pi == nullptr) {
+ if (contexts == nullptr) {
+ return -1;
+ }
+
+ prop_area* serial_pa = contexts->GetSerialPropArea();
+ if (serial_pa == nullptr) {
+ return -1;
+ }
+
+ serial_ptr = serial_pa->serial();
+ } else {
+ serial_ptr = const_cast<atomic_uint_least32_t*>(&pi->serial);
+ }
+
+ uint32_t new_serial;
+ do {
+ int rc;
+ if ((rc = __futex_wait(serial_ptr, old_serial, relative_timeout)) != 0 && rc == -ETIMEDOUT) {
+ return false;
+ }
+ new_serial = load_const_atomic(serial_ptr, memory_order_acquire);
+ } while (new_serial == old_serial);
+
+ *new_serial_ptr = new_serial;
+ return true;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+const prop_info* __system_property_find_nth(unsigned n) {
+ struct find_nth {
+ const uint32_t sought;
+ uint32_t current;
+ const prop_info* result;
+
+ explicit find_nth(uint32_t n) : sought(n), current(0), result(nullptr) {
+ }
+ static void fn(const prop_info* pi, void* ptr) {
+ find_nth* self = reinterpret_cast<find_nth*>(ptr);
+ if (self->current++ == self->sought) self->result = pi;
+ }
+ } state(n);
+ __system_property_foreach(find_nth::fn, &state);
+ return state.result;
+}
+
+__BIONIC_WEAK_FOR_NATIVE_BRIDGE
+int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) {
+ if (contexts == nullptr) {
+ return -1;
+ }
+
+ contexts->ForEach(propfn, cookie);
+
+ return 0;
+}
diff --git a/libc/upstream-freebsd/android/include/freebsd-compat.h b/libc/upstream-freebsd/android/include/freebsd-compat.h
index 8f0a307..e646e23 100644
--- a/libc/upstream-freebsd/android/include/freebsd-compat.h
+++ b/libc/upstream-freebsd/android/include/freebsd-compat.h
@@ -50,6 +50,4 @@
/* FreeBSD has this, but we can't really implement it correctly on Linux. */
#define issetugid() 0
-#define ARG_MAX sysconf(_SC_ARG_MAX)
-
#endif
diff --git a/tests/Android.bp b/tests/Android.bp
index 6ec3c3c..c045c1e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -286,8 +286,9 @@
"gtest_main.cpp",
"gtest_globals.cpp",
],
- static_libs: [
+ whole_static_libs: [
"libbase",
+ "liblog",
],
include_dirs: [
"bionic/libc",
@@ -354,6 +355,9 @@
"gtest_main.cpp",
"gtest_globals_cts.cpp",
],
+ static_libs: [
+ "libbase",
+ ],
cppflags: ["-DUSING_GTEST_OUTPUT_FORMAT"],
shared: {
enabled: false,
diff --git a/tests/Android.mk b/tests/Android.mk
index 98216d7..c945bab 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -75,7 +75,7 @@
LOCAL_CLANG := false
LOCAL_MODULE := bionic-compile-time-tests-g++
-LOCAL_CPPFLAGS := -Wall
+LOCAL_CPPFLAGS := -Wall -Werror
# Disable color diagnostics so the warnings output matches the source
LOCAL_CPPFLAGS += -fdiagnostics-color=never
LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp
@@ -94,7 +94,7 @@
LOCAL_CLANG := true
LOCAL_MODULE := bionic-compile-time-tests-clang++
-LOCAL_CPPFLAGS := -Wall
+LOCAL_CPPFLAGS := -Wall -Werror
LOCAL_CPPFLAGS += -fno-color-diagnostics -ferror-limit=10000
LOCAL_SRC_FILES := fortify_filecheck_diagnostics_test.cpp
include $(BUILD_STATIC_LIBRARY)
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 38afee2..61748c8 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -26,13 +26,17 @@
#include <sys/types.h>
#include <unistd.h>
-#include <bitset>
+#include <set>
+#include <vector>
+#include <android-base/strings.h>
#include <private/android_filesystem_config.h>
// Generated android_ids array
#include "generated_android_ids.h"
+using android::base::Join;
+
enum uid_type_t {
TYPE_SYSTEM,
TYPE_APP
@@ -186,51 +190,86 @@
check_get_passwd("u1_i0", 199000, TYPE_APP);
}
+template <typename T>
+static void expect_ids(const T& ids) {
+ std::set<typename T::key_type> expected_ids;
+ // Ensure that all android_ids are iterated through.
+ for (size_t n = 0; n < android_id_count; ++n) {
+ EXPECT_EQ(1U, ids.count(android_ids[n].aid)) << "android_ids[n].aid: " << android_ids[n].aid;
+ expected_ids.emplace(android_ids[n].aid);
+ }
+
+ auto expect_range = [&ids, &expected_ids](uid_t start, uid_t end) {
+ for (size_t n = start; n <= end; ++n) {
+ EXPECT_EQ(1U, ids.count(n)) << "n: " << n;
+ expected_ids.emplace(n);
+ }
+ };
+
+ // Ensure that all reserved ranges are iterated through.
+ expect_range(AID_OEM_RESERVED_START, AID_OEM_RESERVED_END);
+ expect_range(AID_OEM_RESERVED_2_START, AID_OEM_RESERVED_2_END);
+ expect_range(AID_APP_START, AID_APP_END);
+ expect_range(AID_CACHE_GID_START, AID_CACHE_GID_END);
+ expect_range(AID_EXT_GID_START, AID_EXT_GID_END);
+ expect_range(AID_EXT_CACHE_GID_START, AID_EXT_CACHE_GID_END);
+ expect_range(AID_SHARED_GID_START, AID_SHARED_GID_END);
+ expect_range(AID_ISOLATED_START, AID_ISOLATED_END);
+
+ // Ensure that no other ids were returned.
+ auto return_differences = [&ids, &expected_ids] {
+ std::vector<typename T::key_type> missing_from_ids;
+ std::set_difference(expected_ids.begin(), expected_ids.end(), ids.begin(), ids.end(),
+ std::inserter(missing_from_ids, missing_from_ids.begin()));
+ std::vector<typename T::key_type> extra_in_ids;
+ std::set_difference(ids.begin(), ids.end(), expected_ids.begin(), expected_ids.end(),
+ std::inserter(extra_in_ids, extra_in_ids.begin()));
+ std::string result;
+ if (!missing_from_ids.empty()) {
+ result += "Missing ids from results: " + Join(missing_from_ids, " ");
+ }
+ if (!extra_in_ids.empty()) {
+ if (!result.empty()) result += ", ";
+ result += "Extra ids in results: " + Join(extra_in_ids, " ");
+ }
+ return result;
+ };
+ EXPECT_EQ(expected_ids, ids) << return_differences();
+}
+
TEST(pwd, getpwent_iterate) {
passwd* pwd;
- std::bitset<10000> exist;
- bool application = false;
-
- exist.reset();
+ std::set<uid_t> uids;
setpwent();
while ((pwd = getpwent()) != NULL) {
ASSERT_TRUE(NULL != pwd->pw_name);
+
EXPECT_EQ(pwd->pw_gid, pwd->pw_uid) << "pwd->pw_uid: " << pwd->pw_uid;
EXPECT_EQ(NULL, pwd->pw_passwd) << "pwd->pw_uid: " << pwd->pw_uid;
#ifdef __LP64__
EXPECT_TRUE(NULL == pwd->pw_gecos) << "pwd->pw_uid: " << pwd->pw_uid;
#endif
EXPECT_TRUE(NULL != pwd->pw_shell);
- if (pwd->pw_uid >= exist.size()) {
- EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
- application = true;
- } else {
+ if (pwd->pw_uid < AID_APP_START || pwd->pw_uid == AID_OVERFLOWUID) {
EXPECT_STREQ("/", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
- // TODO(b/27999086): fix this check with the OEM range
- // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
- // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
- // yet, so therefore we do not check for uid's in the OEM range.
- if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
- !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
- EXPECT_FALSE(exist[pwd->pw_uid]) << "pwd->pw_uid: " << pwd->pw_uid;
- }
- exist[pwd->pw_uid] = true;
+ } else {
+ EXPECT_STREQ("/data", pwd->pw_dir) << "pwd->pw_uid: " << pwd->pw_uid;
}
+
+ // TODO(b/27999086): fix this check with the OEM range
+ // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+ // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+ // yet, so therefore we do not check for uid's in the OEM range.
+ if (!(pwd->pw_uid >= 2900 && pwd->pw_uid <= 2999) &&
+ !(pwd->pw_uid >= 5000 && pwd->pw_uid <= 5999)) {
+ EXPECT_EQ(0U, uids.count(pwd->pw_uid)) << "pwd->pw_uid: " << pwd->pw_uid;
+ }
+ uids.emplace(pwd->pw_uid);
}
endpwent();
- // Required content
- for (size_t n = 0; n < android_id_count; ++n) {
- EXPECT_TRUE(exist[android_ids[n].aid]) << "android_ids[n].aid: " << android_ids[n].aid;
- }
- for (size_t n = 2900; n < 2999; ++n) {
- EXPECT_TRUE(exist[n]) << "n: " << n;
- }
- for (size_t n = 5000; n < 5999; ++n) {
- EXPECT_TRUE(exist[n]) << "n: " << n;
- }
- EXPECT_TRUE(application);
+ expect_ids(uids);
}
static void check_group(const group* grp, const char* group_name, gid_t gid) {
@@ -446,10 +485,7 @@
TEST(grp, getgrent_iterate) {
group* grp;
- std::bitset<10000> exist;
- bool application = false;
-
- exist.reset();
+ std::set<gid_t> gids;
setgrent();
while ((grp = getgrent()) != NULL) {
@@ -457,31 +493,18 @@
ASSERT_TRUE(grp->gr_mem != NULL) << "grp->gr_gid: " << grp->gr_gid;
EXPECT_STREQ(grp->gr_name, grp->gr_mem[0]) << "grp->gr_gid: " << grp->gr_gid;
EXPECT_TRUE(grp->gr_mem[1] == NULL) << "grp->gr_gid: " << grp->gr_gid;
- if (grp->gr_gid >= exist.size()) {
- application = true;
- } else {
- // TODO(b/27999086): fix this check with the OEM range
- // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
- // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
- // yet, so therefore we do not check for gid's in the OEM range.
- if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
- !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
- EXPECT_FALSE(exist[grp->gr_gid]) << "grp->gr_gid: " << grp->gr_gid;
- }
- exist[grp->gr_gid] = true;
+
+ // TODO(b/27999086): fix this check with the OEM range
+ // If OEMs add their own AIDs to private/android_filesystem_config.h, this check will fail.
+ // Long term we want to create a better solution for OEMs adding AIDs, but we're not there
+ // yet, so therefore we do not check for gid's in the OEM range.
+ if (!(grp->gr_gid >= 2900 && grp->gr_gid <= 2999) &&
+ !(grp->gr_gid >= 5000 && grp->gr_gid <= 5999)) {
+ EXPECT_EQ(0U, gids.count(grp->gr_gid)) << "grp->gr_gid: " << grp->gr_gid;
}
+ gids.emplace(grp->gr_gid);
}
endgrent();
- // Required content
- for (size_t n = 0; n < android_id_count; ++n) {
- EXPECT_TRUE(exist[android_ids[n].aid]) << "android_ids[n].aid: " << android_ids[n].aid;
- }
- for (size_t n = 2900; n < 2999; ++n) {
- EXPECT_TRUE(exist[n]) << "n: " << n;
- }
- for (size_t n = 5000; n < 5999; ++n) {
- EXPECT_TRUE(exist[n]) << "n: " << n;
- }
- EXPECT_TRUE(application);
+ expect_ids(gids);
}
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 9dcc000..3f59a9c 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -23,6 +23,7 @@
#include <libgen.h>
#include <limits.h>
#include <signal.h>
+#include <spawn.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -35,6 +36,10 @@
#include <utility>
#include <vector>
+#include <android-base/file.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+
#ifndef TEMP_FAILURE_RETRY
/* Used to retry syscalls that can return EINTR. */
@@ -269,49 +274,61 @@
}
static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
- std::string command;
- for (int i = 0; i < argc; ++i) {
- command += argv[i];
- command += " ";
- }
- command += "--gtest_list_tests";
- FILE* fp = popen(command.c_str(), "r");
- if (fp == NULL) {
- perror("popen");
+ std::vector<const char*> args;
+ for (int i = 0; i < argc; ++i) args.push_back(argv[i]);
+ args.push_back("--gtest_list_tests");
+ args.push_back(nullptr);
+
+ // We use posix_spawn(3) rather than the simpler popen(3) because we don't want an intervening
+ // surprise shell invocation making quoting interesting for --gtest_filter (http://b/68949647).
+
+ android::base::unique_fd read_fd;
+ android::base::unique_fd write_fd;
+ if (!android::base::Pipe(&read_fd, &write_fd)) {
+ perror("pipe");
return false;
}
- char buf[200];
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- char* p = buf;
+ posix_spawn_file_actions_t fa;
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addclose(&fa, read_fd);
+ posix_spawn_file_actions_adddup2(&fa, write_fd, 1);
+ posix_spawn_file_actions_adddup2(&fa, write_fd, 2);
+ posix_spawn_file_actions_addclose(&fa, write_fd);
- while (*p != '\0' && isspace(*p)) {
- ++p;
- }
- if (*p == '\0') continue;
- char* start = p;
- while (*p != '\0' && !isspace(*p)) {
- ++p;
- }
- char* end = p;
- while (*p != '\0' && isspace(*p)) {
- ++p;
- }
- if (*p != '\0' && *p != '#') {
- // This is not we want, gtest must meet with some error when parsing the arguments.
- fprintf(stderr, "argument error, check with --help\n");
- return false;
- }
- *end = '\0';
- if (*(end - 1) == '.') {
- *(end - 1) = '\0';
- testcase_list.push_back(TestCase(start));
+ pid_t pid;
+ int result = posix_spawnp(&pid, argv[0], &fa, nullptr, const_cast<char**>(args.data()), nullptr);
+ posix_spawn_file_actions_destroy(&fa);
+ if (result == -1) {
+ perror("posix_spawn");
+ return false;
+ }
+ write_fd.reset();
+
+ std::string content;
+ if (!android::base::ReadFdToString(read_fd, &content)) {
+ perror("ReadFdToString");
+ return false;
+ }
+
+ for (auto& line : android::base::Split(content, "\n")) {
+ line = android::base::Split(line, "#")[0];
+ line = android::base::Trim(line);
+ if (line.empty()) continue;
+ if (android::base::EndsWith(line, ".")) {
+ line.pop_back();
+ testcase_list.push_back(TestCase(line.c_str()));
} else {
- testcase_list.back().AppendTest(start);
+ testcase_list.back().AppendTest(line.c_str());
}
}
- int result = pclose(fp);
- return (result != -1 && WEXITSTATUS(result) == 0);
+
+ int status;
+ if (waitpid(pid, &status, 0) != pid) {
+ perror("waitpid");
+ return false;
+ }
+ return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
}
// Part of the following *Print functions are copied from external/gtest/src/gtest.cc:
@@ -1249,3 +1266,24 @@
TEST_F(bionic_selftest_DeathTest, fail) {
ASSERT_EXIT(deathtest_helper_fail(), ::testing::ExitedWithCode(0), "");
}
+
+class BionicSelfTest : public ::testing::TestWithParam<bool> {
+};
+
+TEST_P(BionicSelfTest, test_success) {
+ ASSERT_EQ(GetParam(), GetParam());
+}
+
+INSTANTIATE_TEST_CASE_P(bionic_selftest, BionicSelfTest, ::testing::Values(true, false));
+
+template <typename T>
+class bionic_selftest_TestT : public ::testing::Test {
+};
+
+typedef ::testing::Types<char, int> MyTypes;
+
+TYPED_TEST_CASE(bionic_selftest_TestT, MyTypes);
+
+TYPED_TEST(bionic_selftest_TestT, test_success) {
+ ASSERT_EQ(true, true);
+}
diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk
index a54318d..5bd028d 100644
--- a/tests/libs/Android.mk
+++ b/tests/libs/Android.mk
@@ -17,7 +17,7 @@
LOCAL_PATH := $(call my-dir)
TEST_PATH := $(LOCAL_PATH)/..
-common_cppflags :=
+common_cppflags := -Wall -Werror
common_additional_dependencies := \
$(LOCAL_PATH)/Android.mk \
$(LOCAL_PATH)/Android.build.dt_runpath.mk \
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 456ddde..022da4d 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1017,36 +1017,11 @@
}
TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
- // Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
-
- // Get our current limit, and set things up so we restore the limit.
- rlimit rl;
- ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
- uint64_t original_rlim_cur = rl.rlim_cur;
- if (rl.rlim_cur == RLIM_INFINITY) {
- rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
- }
- auto guard = android::base::make_scope_guard([&rl, original_rlim_cur]() {
- rl.rlim_cur = original_rlim_cur;
- ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
- });
-
- // _SC_ARG_MAX should be 1/4 the stack size.
- EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
-
- // If you have a really small stack, the kernel still guarantees "32 pages" (fs/exec.c).
- rl.rlim_cur = 1024;
- rl.rlim_max = RLIM_INFINITY;
- ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
-
- EXPECT_EQ(static_cast<long>(32 * sysconf(_SC_PAGE_SIZE)), sysconf(_SC_ARG_MAX));
-
- // With a 128-page stack limit, we know exactly what _SC_ARG_MAX should be...
- rl.rlim_cur = 128 * sysconf(_SC_PAGE_SIZE);
- rl.rlim_max = RLIM_INFINITY;
- ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
-
- EXPECT_EQ(static_cast<long>((128 * sysconf(_SC_PAGE_SIZE)) / 4), sysconf(_SC_ARG_MAX));
+ // https://lkml.org/lkml/2017/11/15/813.
+#if !defined(ARG_MAX)
+#define ARG_MAX 131072
+#endif
+ ASSERT_EQ(ARG_MAX, sysconf(_SC_ARG_MAX));
}
TEST(UNISTD_TEST, dup2_same) {