Merge keystone/mirror-android12-5.10 into keystone/android12-5.10-keystone-qcom-dev

* keystone/mirror-android12-5.10:
  ANDROID: Add an extra wake flag for android vendor use
  FROMLIST: tools/bootconfig: Fix a build error accroding to undefined fallthrough
  FROMLIST: bootconfig: Change array value to use child node
  FROMLIST: bootconfig: Support mixing a value and subkeys under a key
  FROMLIST: tools/bootconfig: Support mixed value and subkey test cases
  FROMLIST: docs: bootconfig: Update for mixing value and subkeys
  FROMLIST: bootconfig: Share the checksum function with tools
  FROMGIT: kfence: unconditionally use unbound work queue
  Revert "ANDROID: mm: oom_kill: reap memory of a task that receives SIGKILL"
  ANDROID: signal: Add vendor hook for memory reaping
  Revert "Revert "ANDROID: usb: dwc3: gadget: don't cancel the started requests""
  ANDROID: vendor_hooks: Export the tracepoints task_rename
  ANDROID: GKI: Request enable some kernel configs for background speed limit function
  ANDROID: usb: export tracepoint for dwc3_complete_trb
  FROMGIT: usb: typec: tcpm: Properly handle Alert and Status Messages
  FROMGIT: usb: typec: tcpm: cancel vdm and state machine hrtimer when unregister tcpm port
  FROMGIT: usb: typec: tcpm: cancel frs hrtimer when unregister tcpm port
  FROMGIT: usb: typec: tcpm: cancel send discover hrtimer when unregister tcpm port
  FROMGIT: usb: gadget: f_fs: Ensure io_completion_wq is idle during unbind
Signed-off-by: Chris Gross <chrisgross@google.com>
Bug: 181822795
Bug: 183237066
Bug: 188778499
Bug: 189130101
Bug: 189705988
Bug: 189803002
Bug: 189858948
Bug: 189985971
Change-Id: Ic8fe55b359f953bc59d88caa208d983072d08e23
This commit is contained in:
Chris Gross 2021-06-04 10:17:26 -07:00
commit b208080ef8
30 changed files with 273 additions and 123 deletions

View File

@ -89,13 +89,35 @@ you can use ``+=`` operator. For example::
In this case, the key ``foo`` has ``bar``, ``baz`` and ``qux``.
However, a sub-key and a value can not co-exist under a parent key.
For example, following config is NOT allowed.::
Moreover, sub-keys and a value can coexist under a parent key.
For example, following config is allowed.::
foo = value1
foo.bar = value2 # !ERROR! subkey "bar" and value "value1" can NOT co-exist
foo.bar := value2 # !ERROR! even with the override operator, this is NOT allowed.
foo.bar = value2
foo := value3 # This will update foo's value.
Note, since there is no syntax to put a raw value directly under a
structured key, you have to define it outside of the brace. For example::
foo {
bar = value1
bar {
baz = value2
qux = value3
}
}
Also, the order of the value node under a key is fixed. If there
are a value and subkeys, the value is always the first child node
of the key. Thus if user specifies subkeys first, e.g.::
foo.bar = value1
foo = value2
In the program (and /proc/bootconfig), it will be shown as below::
foo = value2
foo.bar = value1
Comments
--------

View File

@ -4683,10 +4683,6 @@
(that will set all pages holding image data
during restoration read-only).
reap_mem_when_killed_by=
The name of a process, the kill signal from which to a process
make its memory reaped with oom reaper.
retain_initrd [RAM] Keep initrd memory after extraction
rfkill.default_state=

View File

@ -227,20 +227,29 @@ CONFIG_MAC802154=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_VSOCKETS=y
CONFIG_BPF_JIT=y
CONFIG_BT=y

View File

@ -204,20 +204,29 @@ CONFIG_MAC802154=y
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_HTB=y
CONFIG_NET_SCH_PRIO=y
CONFIG_NET_SCH_MULTIQ=y
CONFIG_NET_SCH_TBF=y
CONFIG_NET_SCH_NETEM=y
CONFIG_NET_SCH_INGRESS=y
CONFIG_NET_CLS_BASIC=y
CONFIG_NET_CLS_TCINDEX=y
CONFIG_NET_CLS_FW=y
CONFIG_NET_CLS_U32=y
CONFIG_CLS_U32_MARK=y
CONFIG_NET_CLS_FLOW=y
CONFIG_NET_CLS_BPF=y
CONFIG_NET_CLS_MATCHALL=y
CONFIG_NET_EMATCH=y
CONFIG_NET_EMATCH_CMP=y
CONFIG_NET_EMATCH_NBYTE=y
CONFIG_NET_EMATCH_U32=y
CONFIG_NET_EMATCH_META=y
CONFIG_NET_EMATCH_TEXT=y
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_MIRRED=y
CONFIG_NET_ACT_SKBEDIT=y
CONFIG_VSOCKETS=y
CONFIG_BPF_JIT=y
CONFIG_BT=y

View File

@ -83,6 +83,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_restore_priority);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_wakeup_ilocked);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_send_sig_info);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_killed);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_finished);

View File

@ -1823,8 +1823,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
{
struct dwc3_gadget_ep_cmd_params params;
struct dwc3 *dwc = dep->dwc;
struct dwc3_request *req;
struct dwc3_request *tmp;
int ret;
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
@ -1873,16 +1871,14 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
dwc3_stop_active_transfer(dep, true, true);
list_for_each_entry_safe(req, tmp, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_STALLED);
if (!list_empty(&dep->started_list))
dep->flags |= DWC3_EP_DELAY_START;
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
dep->flags |= DWC3_EP_PENDING_CLEAR_STALL;
return 0;
}
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
ret = dwc3_send_clear_stall_ep_cmd(dep);
if (ret) {
dev_err(dwc->dev, "failed to clear STALL on %s\n",

View File

@ -15,3 +15,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(dwc3_readl);
EXPORT_TRACEPOINT_SYMBOL_GPL(dwc3_writel);
EXPORT_TRACEPOINT_SYMBOL_GPL(dwc3_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(dwc3_ctrl_req);
EXPORT_TRACEPOINT_SYMBOL_GPL(dwc3_complete_trb);

View File

@ -3570,6 +3570,9 @@ static void ffs_func_unbind(struct usb_configuration *c,
ffs->func = NULL;
}
/* Drain any pending AIO completions */
drain_workqueue(ffs->io_completion_wq);
if (!--opts->refcnt)
functionfs_unbind(ffs);

View File

@ -2220,20 +2220,25 @@ static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload,
if (!type) {
tcpm_log(port, "Alert message received with no type");
tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
return;
}
/* Just handling non-battery alerts for now */
if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) {
switch (port->state) {
case SRC_READY:
case SNK_READY:
if (port->pwr_role == TYPEC_SOURCE) {
port->upcoming_state = GET_STATUS_SEND;
tcpm_ams_start(port, GETTING_SOURCE_SINK_STATUS);
} else {
/*
* Do not check SinkTxOk here in case the Source doesn't set its Rp to
* SinkTxOk in time.
*/
port->ams = GETTING_SOURCE_SINK_STATUS;
tcpm_set_state(port, GET_STATUS_SEND, 0);
break;
default:
tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
break;
}
} else {
tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
}
}
@ -2480,7 +2485,12 @@ static void tcpm_pd_data_request(struct tcpm_port *port,
tcpm_pd_handle_state(port, BIST_RX, BIST, 0);
break;
case PD_DATA_ALERT:
tcpm_handle_alert(port, msg->payload, cnt);
if (port->state != SRC_READY && port->state != SNK_READY)
tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
NONE_AMS, 0);
else
tcpm_handle_alert(port, msg->payload, cnt);
break;
case PD_DATA_BATT_STATUS:
case PD_DATA_GET_COUNTRY_INFO:
@ -2804,24 +2814,16 @@ static void tcpm_pd_ext_msg_request(struct tcpm_port *port,
switch (type) {
case PD_EXT_STATUS:
/*
* If PPS related events raised then get PPS status to clear
* (see USB PD 3.0 Spec, 6.5.2.4)
*/
if (msg->ext_msg.data[USB_PD_EXT_SDB_EVENT_FLAGS] &
USB_PD_EXT_SDB_PPS_EVENTS)
tcpm_pd_handle_state(port, GET_PPS_STATUS_SEND,
GETTING_SOURCE_SINK_STATUS, 0);
else
tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
break;
case PD_EXT_PPS_STATUS:
/*
* For now the PPS status message is used to clear events
* and nothing more.
*/
tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0);
if (port->ams == GETTING_SOURCE_SINK_STATUS) {
tcpm_ams_finish(port);
tcpm_set_state(port, ready_state(port), 0);
} else {
/* unexpected Status or PPS_Status Message */
tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
NONE_AMS, 0);
}
break;
case PD_EXT_SOURCE_CAP_EXT:
case PD_EXT_GET_BATT_CAP:
@ -6472,6 +6474,11 @@ void tcpm_unregister_port(struct tcpm_port *port)
{
int i;
hrtimer_cancel(&port->send_discover_timer);
hrtimer_cancel(&port->enable_frs_timer);
hrtimer_cancel(&port->vdm_state_machine_timer);
hrtimer_cancel(&port->state_machine_timer);
tcpm_reset_port(port);
for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++)
typec_unregister_altmode(port->port_altmode[i]);

View File

@ -75,6 +75,8 @@
#include <trace/events/sched.h>
#include <trace/hooks/sched.h>
EXPORT_TRACEPOINT_SYMBOL_GPL(task_rename);
static int bprm_creds_from_file(struct linux_binprm *bprm);
int suid_dumpable = 0;

View File

@ -49,7 +49,7 @@ static int __init copy_xbc_key_value_list(char *dst, size_t size)
else
q = '"';
ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
q, val, q, vnode->next ? ", " : "\n");
q, val, q, xbc_node_is_array(vnode) ? ", " : "\n");
if (ret < 0)
goto out;
dst += ret;

View File

@ -16,6 +16,26 @@
#define BOOTCONFIG_ALIGN (1 << BOOTCONFIG_ALIGN_SHIFT)
#define BOOTCONFIG_ALIGN_MASK (BOOTCONFIG_ALIGN - 1)
/**
* xbc_calc_checksum() - Calculate checksum of bootconfig
* @data: Bootconfig data.
* @size: The size of the bootconfig data.
*
* Calculate the checksum value of the bootconfig data.
* The checksum will be used with the BOOTCONFIG_MAGIC and the size for
* embedding the bootconfig in the initrd image.
*/
static inline __init u32 xbc_calc_checksum(void *data, u32 size)
{
unsigned char *p = data;
u32 ret = 0;
while (size--)
ret += *p++;
return ret;
}
/* XBC tree node */
struct xbc_node {
u16 next;
@ -71,7 +91,7 @@ static inline __init bool xbc_node_is_key(struct xbc_node *node)
*/
static inline __init bool xbc_node_is_array(struct xbc_node *node)
{
return xbc_node_is_value(node) && node->next != 0;
return xbc_node_is_value(node) && node->child != 0;
}
/**
@ -80,6 +100,8 @@ static inline __init bool xbc_node_is_array(struct xbc_node *node)
*
* Test the @node is a leaf key node which is a key node and has a value node
* or no child. Returns true if it is a leaf node, or false if not.
* Note that the leaf node can have subkey nodes in addition to the
* value node.
*/
static inline __init bool xbc_node_is_leaf(struct xbc_node *node)
{
@ -129,6 +151,23 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
return xbc_node_find_child(NULL, key);
}
/**
* xbc_node_get_subkey() - Return the first subkey node if exists
* @node: Parent node
*
* Return the first subkey node of the @node. If the @node has no child
* or only value node, this will return NULL.
*/
static inline struct xbc_node * __init xbc_node_get_subkey(struct xbc_node *node)
{
struct xbc_node *child = xbc_node_get_child(node);
if (child && xbc_node_is_value(child))
return xbc_node_get_next(child);
else
return child;
}
/**
* xbc_array_for_each_value() - Iterate value nodes on an array
* @anode: An XBC arraied value node
@ -140,7 +179,7 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
*/
#define xbc_array_for_each_value(anode, value) \
for (value = xbc_node_get_data(anode); anode != NULL ; \
anode = xbc_node_get_next(anode), \
anode = xbc_node_get_child(anode), \
value = anode ? xbc_node_get_data(anode) : NULL)
/**
@ -149,11 +188,24 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
* @child: Iterated XBC node.
*
* Iterate child nodes of @parent. Each child nodes are stored to @child.
* The @child can be mixture of a value node and subkey nodes.
*/
#define xbc_node_for_each_child(parent, child) \
for (child = xbc_node_get_child(parent); child != NULL ; \
child = xbc_node_get_next(child))
/**
* xbc_node_for_each_subkey() - Iterate child subkey nodes
* @parent: An XBC node.
* @child: Iterated XBC node.
*
* Iterate subkey nodes of @parent. Each child nodes are stored to @child.
* The @child is only the subkey node.
*/
#define xbc_node_for_each_subkey(parent, child) \
for (child = xbc_node_get_subkey(parent); child != NULL ; \
child = xbc_node_get_next(child))
/**
* xbc_node_for_each_array_value() - Iterate array entries of geven key
* @node: An XBC node.
@ -171,7 +223,7 @@ static inline struct xbc_node * __init xbc_find_node(const char *key)
*/
#define xbc_node_for_each_array_value(node, key, anode, value) \
for (value = xbc_node_find_value(node, key, &anode); value != NULL; \
anode = xbc_node_get_next(anode), \
anode = xbc_node_get_child(anode), \
value = anode ? xbc_node_get_data(anode) : NULL)
/**

View File

@ -130,6 +130,6 @@ extern int sysctl_oom_dump_tasks;
extern int sysctl_oom_kill_allocating_task;
extern int sysctl_panic_on_oom;
/* calls for LMK reaper */
/* call for adding killed process to reaper. */
extern void add_to_oom_reaper(struct task_struct *p);
#endif /* _INCLUDE_LINUX_OOM_H */

View File

@ -24,8 +24,4 @@ enum usb_pd_ext_sdb_fields {
#define USB_PD_EXT_SDB_EVENT_OVP BIT(3)
#define USB_PD_EXT_SDB_EVENT_CF_CV_MODE BIT(4)
#define USB_PD_EXT_SDB_PPS_EVENTS (USB_PD_EXT_SDB_EVENT_OCP | \
USB_PD_EXT_SDB_EVENT_OTP | \
USB_PD_EXT_SDB_EVENT_OVP)
#endif /* __LINUX_USB_PD_EXT_SDB_H */

View File

@ -12,6 +12,9 @@ struct task_struct;
DECLARE_HOOK(android_vh_do_send_sig_info,
TP_PROTO(int sig, struct task_struct *killer, struct task_struct *dst),
TP_ARGS(sig, killer, dst));
DECLARE_HOOK(android_vh_process_killed,
TP_PROTO(struct task_struct *task, bool *reap),
TP_ARGS(task, reap));
#endif /* _TRACE_HOOK_SIGNAL_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -388,16 +388,6 @@ static char * __init xbc_make_cmdline(const char *key)
return new_cmdline;
}
static u32 boot_config_checksum(unsigned char *p, u32 size)
{
u32 ret = 0;
while (size--)
ret += *p++;
return ret;
}
static int __init bootconfig_params(char *param, char *val,
const char *unused, void *arg)
{
@ -441,7 +431,7 @@ static void __init setup_boot_config(const char *cmdline)
return;
}
if (boot_config_checksum((unsigned char *)data, size) != csum) {
if (xbc_calc_checksum(data, size) != csum) {
pr_err("bootconfig checksum failed\n");
return;
}

View File

@ -5026,7 +5026,7 @@ asmlinkage __visible void __sched preempt_schedule_irq(void)
int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags,
void *key)
{
WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~WF_SYNC);
WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~(WF_SYNC | WF_ANDROID_VENDOR));
return try_to_wake_up(curr->private, mode, wake_flags);
}
EXPORT_SYMBOL(default_wake_function);

View File

@ -1755,6 +1755,7 @@ static inline int task_on_rq_migrating(struct task_struct *p)
#define WF_FORK 0x02 /* Child wakeup after fork */
#define WF_MIGRATED 0x04 /* Internal use, task got migrated */
#define WF_ON_CPU 0x08 /* Wakee is on_cpu */
#define WF_ANDROID_VENDOR 0x1000 /* Vendor specific for Android */
/*
* To aid in avoiding the subversion of "niceness" due to uneven distribution

View File

@ -67,18 +67,6 @@ static struct kmem_cache *sigqueue_cachep;
int print_fatal_signals __read_mostly;
static char reaper_comm[TASK_COMM_LEN];
static __init int setup_mem_reap(char *str)
{
if (!str)
return 0;
strlcpy(reaper_comm, str, TASK_COMM_LEN);
return 1;
}
__setup("reap_mem_when_killed_by=", setup_mem_reap);
static void __user *sig_handler(struct task_struct *t, int sig)
{
return t->sighand->action[sig - 1].sa.sa_handler;
@ -1428,9 +1416,13 @@ int group_send_sig_info(int sig, struct kernel_siginfo *info,
if (!ret && sig) {
ret = do_send_sig_info(sig, info, p, type);
if (!ret && sig == SIGKILL &&
!strcmp(current->comm, reaper_comm))
add_to_oom_reaper(p);
if (!ret && sig == SIGKILL) {
bool reap = false;
trace_android_vh_process_killed(current, &reap);
if (reap)
add_to_oom_reaper(p);
}
}
return ret;

View File

@ -156,7 +156,7 @@ xbc_node_find_child(struct xbc_node *parent, const char *key)
struct xbc_node *node;
if (parent)
node = xbc_node_get_child(parent);
node = xbc_node_get_subkey(parent);
else
node = xbc_root_node();
@ -164,7 +164,7 @@ xbc_node_find_child(struct xbc_node *parent, const char *key)
if (!xbc_node_match_prefix(node, &key))
node = xbc_node_get_next(node);
else if (*key != '\0')
node = xbc_node_get_child(node);
node = xbc_node_get_subkey(node);
else
break;
}
@ -274,6 +274,8 @@ int __init xbc_node_compose_key_after(struct xbc_node *root,
struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
struct xbc_node *node)
{
struct xbc_node *next;
if (unlikely(!xbc_data))
return NULL;
@ -282,6 +284,13 @@ struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
if (!node)
node = xbc_nodes;
} else {
/* Leaf node may have a subkey */
next = xbc_node_get_subkey(node);
if (next) {
node = next;
goto found;
}
if (node == root) /* @root was a leaf, no child node. */
return NULL;
@ -296,6 +305,7 @@ struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
node = xbc_node_get_next(node);
}
found:
while (node && !xbc_node_is_leaf(node))
node = xbc_node_get_child(node);
@ -367,18 +377,28 @@ static inline __init struct xbc_node *xbc_last_sibling(struct xbc_node *node)
return node;
}
static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
static inline __init struct xbc_node *xbc_last_child(struct xbc_node *node)
{
while (node->child)
node = xbc_node_get_child(node);
return node;
}
static struct xbc_node * __init __xbc_add_sibling(char *data, u32 flag, bool head)
{
struct xbc_node *sib, *node = xbc_add_node(data, flag);
if (node) {
if (!last_parent) {
/* Ignore @head in this case */
node->parent = XBC_NODE_MAX;
sib = xbc_last_sibling(xbc_nodes);
sib->next = xbc_node_index(node);
} else {
node->parent = xbc_node_index(last_parent);
if (!last_parent->child) {
if (!last_parent->child || head) {
node->next = last_parent->child;
last_parent->child = xbc_node_index(node);
} else {
sib = xbc_node_get_child(last_parent);
@ -392,6 +412,16 @@ static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
return node;
}
static inline struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
{
return __xbc_add_sibling(data, flag, false);
}
static inline struct xbc_node * __init xbc_add_head_sibling(char *data, u32 flag)
{
return __xbc_add_sibling(data, flag, true);
}
static inline __init struct xbc_node *xbc_add_child(char *data, u32 flag)
{
struct xbc_node *node = xbc_add_sibling(data, flag);
@ -517,17 +547,20 @@ static int __init xbc_parse_array(char **__v)
char *next;
int c = 0;
if (last_parent->child)
last_parent = xbc_node_get_child(last_parent);
do {
c = __xbc_parse_value(__v, &next);
if (c < 0)
return c;
node = xbc_add_sibling(*__v, XBC_VALUE);
node = xbc_add_child(*__v, XBC_VALUE);
if (!node)
return -ENOMEM;
*__v = next;
} while (c == ',');
node->next = 0;
node->child = 0;
return c;
}
@ -557,8 +590,9 @@ static int __init __xbc_add_key(char *k)
node = find_match_node(xbc_nodes, k);
else {
child = xbc_node_get_child(last_parent);
/* Since the value node is the first child, skip it. */
if (child && xbc_node_is_value(child))
return xbc_parse_error("Subkey is mixed with value", k);
child = xbc_node_get_next(child);
node = find_match_node(child, k);
}
@ -601,23 +635,29 @@ static int __init xbc_parse_kv(char **k, char *v, int op)
if (ret)
return ret;
child = xbc_node_get_child(last_parent);
if (child) {
if (xbc_node_is_key(child))
return xbc_parse_error("Value is mixed with subkey", v);
else if (op == '=')
return xbc_parse_error("Value is redefined", v);
}
c = __xbc_parse_value(&v, &next);
if (c < 0)
return c;
if (op == ':' && child) {
xbc_init_node(child, v, XBC_VALUE);
} else if (!xbc_add_sibling(v, XBC_VALUE))
child = xbc_node_get_child(last_parent);
if (child && xbc_node_is_value(child)) {
if (op == '=')
return xbc_parse_error("Value is redefined", v);
if (op == ':') {
unsigned short nidx = child->next;
xbc_init_node(child, v, XBC_VALUE);
child->next = nidx; /* keep subkeys */
goto array;
}
/* op must be '+' */
last_parent = xbc_last_child(child);
}
/* The value node should always be the first child */
if (!xbc_add_head_sibling(v, XBC_VALUE))
return -ENOMEM;
array:
if (c == ',') { /* Array */
c = xbc_parse_array(&next);
if (c < 0)

View File

@ -636,7 +636,7 @@ static void toggle_allocation_gate(struct work_struct *work)
/* Disable static key and reset timer. */
static_branch_disable(&kfence_allocation_key);
#endif
queue_delayed_work(system_power_efficient_wq, &kfence_timer,
queue_delayed_work(system_unbound_wq, &kfence_timer,
msecs_to_jiffies(kfence_sample_interval));
}
static DECLARE_DELAYED_WORK(kfence_timer, toggle_allocation_gate);
@ -666,7 +666,7 @@ void __init kfence_init(void)
}
WRITE_ONCE(kfence_enabled, true);
queue_delayed_work(system_power_efficient_wq, &kfence_timer, 0);
queue_delayed_work(system_unbound_wq, &kfence_timer, 0);
pr_info("initialized - using %lu bytes for %d objects at 0x%p-0x%p\n", KFENCE_POOL_SIZE,
CONFIG_KFENCE_NUM_OBJECTS, (void *)__kfence_pool,
(void *)(__kfence_pool + KFENCE_POOL_SIZE));

View File

@ -4,4 +4,8 @@
#include "../../../../include/linux/bootconfig.h"
#ifndef fallthrough
# define fallthrough
#endif
#endif

View File

@ -27,7 +27,7 @@ static int xbc_show_value(struct xbc_node *node, bool semicolon)
q = '\'';
else
q = '"';
printf("%c%s%c%s", q, val, q, node->next ? ", " : eol);
printf("%c%s%c%s", q, val, q, xbc_node_is_array(node) ? ", " : eol);
i++;
}
return i;
@ -35,30 +35,55 @@ static int xbc_show_value(struct xbc_node *node, bool semicolon)
static void xbc_show_compact_tree(void)
{
struct xbc_node *node, *cnode;
struct xbc_node *node, *cnode = NULL, *vnode;
int depth = 0, i;
node = xbc_root_node();
while (node && xbc_node_is_key(node)) {
for (i = 0; i < depth; i++)
printf("\t");
cnode = xbc_node_get_child(node);
if (!cnode)
cnode = xbc_node_get_child(node);
while (cnode && xbc_node_is_key(cnode) && !cnode->next) {
vnode = xbc_node_get_child(cnode);
/*
* If @cnode has value and subkeys, this
* should show it as below.
*
* key(@node) {
* key(@cnode) = value;
* key(@cnode) {
* subkeys;
* }
* }
*/
if (vnode && xbc_node_is_value(vnode) && vnode->next)
break;
printf("%s.", xbc_node_get_data(node));
node = cnode;
cnode = xbc_node_get_child(node);
cnode = vnode;
}
if (cnode && xbc_node_is_key(cnode)) {
printf("%s {\n", xbc_node_get_data(node));
depth++;
node = cnode;
cnode = NULL;
continue;
} else if (cnode && xbc_node_is_value(cnode)) {
printf("%s = ", xbc_node_get_data(node));
xbc_show_value(cnode, true);
/*
* If @node has value and subkeys, continue
* looping on subkeys with same node.
*/
if (cnode->next) {
cnode = xbc_node_get_next(cnode);
continue;
}
} else {
printf("%s;\n", xbc_node_get_data(node));
}
cnode = NULL;
if (node->next) {
node = xbc_node_get_next(node);
@ -70,10 +95,12 @@ static void xbc_show_compact_tree(void)
return;
if (!xbc_node_get_child(node)->next)
continue;
depth--;
for (i = 0; i < depth; i++)
printf("\t");
printf("}\n");
if (depth) {
depth--;
for (i = 0; i < depth; i++)
printf("\t");
printf("}\n");
}
}
node = xbc_node_get_next(node);
}
@ -88,8 +115,10 @@ static void xbc_show_list(void)
xbc_for_each_key_value(leaf, val) {
ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
if (ret < 0)
if (ret < 0) {
fprintf(stderr, "Failed to compose key %d\n", ret);
break;
}
printf("%s = ", key);
if (!val || val[0] == '\0') {
printf("\"\"\n");
@ -99,17 +128,6 @@ static void xbc_show_list(void)
}
}
/* Simple real checksum */
static int checksum(unsigned char *buf, int len)
{
int i, sum = 0;
for (i = 0; i < len; i++)
sum += buf[i];
return sum;
}
#define PAGE_SIZE 4096
static int load_xbc_fd(int fd, char **buf, int size)
@ -205,7 +223,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
return ret;
/* Wrong Checksum */
rcsum = checksum((unsigned char *)*buf, size);
rcsum = xbc_calc_checksum(*buf, size);
if (csum != rcsum) {
pr_err("checksum error: %d != %d\n", csum, rcsum);
return -EINVAL;
@ -354,7 +372,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
return ret;
}
size = strlen(buf) + 1;
csum = checksum((unsigned char *)buf, size);
csum = xbc_calc_checksum(buf, size);
/* Backup the bootconfig data */
data = calloc(size + BOOTCONFIG_ALIGN +

View File

@ -1,3 +0,0 @@
key.subkey = value
# We can not override pre-defined subkeys with value
key := value

View File

@ -1,3 +0,0 @@
key = value
# We can not override pre-defined value with subkey
key.subkey := value

View File

@ -0,0 +1,4 @@
key = foo
keyx.subkey = value
key += bar

View File

@ -0,0 +1,6 @@
# mixed key and subkeys with braces
key = value
key {
subkey1
subkey2 = foo
}

View File

@ -0,0 +1,4 @@
key.foo = bar
key = value
# mixed key value can be overridden
key := value2