bootconfig: Allocate xbc_data inside xbc_init()
Allocate 'xbc_data' in the xbc_init() so that it does not need to care about the ownership of the copied data. Link: https://lkml.kernel.org/r/163177339986.682366.898762699429769117.stgit@devnote2 Suggested-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
Родитель
6644c654ea
Коммит
bdac5c2b24
|
@ -271,7 +271,7 @@ static inline int __init xbc_node_compose_key(struct xbc_node *node,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XBC node initializer */
|
/* XBC node initializer */
|
||||||
int __init xbc_init(char *buf, const char **emsg, int *epos);
|
int __init xbc_init(const char *buf, size_t size, const char **emsg, int *epos);
|
||||||
|
|
||||||
|
|
||||||
/* XBC cleanup data structures */
|
/* XBC cleanup data structures */
|
||||||
|
|
13
init/main.c
13
init/main.c
|
@ -409,7 +409,7 @@ static void __init setup_boot_config(void)
|
||||||
const char *msg;
|
const char *msg;
|
||||||
int pos;
|
int pos;
|
||||||
u32 size, csum;
|
u32 size, csum;
|
||||||
char *data, *copy, *err;
|
char *data, *err;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Cut out the bootconfig data even if we have no bootconfig option */
|
/* Cut out the bootconfig data even if we have no bootconfig option */
|
||||||
|
@ -442,16 +442,7 @@ static void __init setup_boot_config(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
|
ret = xbc_init(data, size, &msg, &pos);
|
||||||
if (!copy) {
|
|
||||||
pr_err("Failed to allocate memory for bootconfig\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(copy, data, size);
|
|
||||||
copy[size] = '\0';
|
|
||||||
|
|
||||||
ret = xbc_init(copy, &msg, &pos);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
pr_err("Failed to init bootconfig: %s.\n", msg);
|
pr_err("Failed to init bootconfig: %s.\n", msg);
|
||||||
|
|
|
@ -789,6 +789,7 @@ static int __init xbc_verify_tree(void)
|
||||||
*/
|
*/
|
||||||
void __init xbc_destroy_all(void)
|
void __init xbc_destroy_all(void)
|
||||||
{
|
{
|
||||||
|
memblock_free_ptr(xbc_data, xbc_data_size);
|
||||||
xbc_data = NULL;
|
xbc_data = NULL;
|
||||||
xbc_data_size = 0;
|
xbc_data_size = 0;
|
||||||
xbc_node_num = 0;
|
xbc_node_num = 0;
|
||||||
|
@ -799,19 +800,20 @@ void __init xbc_destroy_all(void)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xbc_init() - Parse given XBC file and build XBC internal tree
|
* xbc_init() - Parse given XBC file and build XBC internal tree
|
||||||
* @buf: boot config text
|
* @data: The boot config text original data
|
||||||
|
* @size: The size of @data
|
||||||
* @emsg: A pointer of const char * to store the error message
|
* @emsg: A pointer of const char * to store the error message
|
||||||
* @epos: A pointer of int to store the error position
|
* @epos: A pointer of int to store the error position
|
||||||
*
|
*
|
||||||
* This parses the boot config text in @buf. @buf must be a
|
* This parses the boot config text in @data. @size must be smaller
|
||||||
* null terminated string and smaller than XBC_DATA_MAX.
|
* than XBC_DATA_MAX.
|
||||||
* Return the number of stored nodes (>0) if succeeded, or -errno
|
* Return the number of stored nodes (>0) if succeeded, or -errno
|
||||||
* if there is any error.
|
* if there is any error.
|
||||||
* In error cases, @emsg will be updated with an error message and
|
* In error cases, @emsg will be updated with an error message and
|
||||||
* @epos will be updated with the error position which is the byte offset
|
* @epos will be updated with the error position which is the byte offset
|
||||||
* of @buf. If the error is not a parser error, @epos will be -1.
|
* of @buf. If the error is not a parser error, @epos will be -1.
|
||||||
*/
|
*/
|
||||||
int __init xbc_init(char *buf, const char **emsg, int *epos)
|
int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos)
|
||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int ret, c;
|
int ret, c;
|
||||||
|
@ -824,28 +826,35 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
|
||||||
*emsg = "Bootconfig is already initialized";
|
*emsg = "Bootconfig is already initialized";
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
if (size > XBC_DATA_MAX || size == 0) {
|
||||||
ret = strlen(buf);
|
|
||||||
if (ret > XBC_DATA_MAX - 1 || ret == 0) {
|
|
||||||
if (emsg)
|
if (emsg)
|
||||||
*emsg = ret ? "Config data is too big" :
|
*emsg = size ? "Config data is too big" :
|
||||||
"Config data is empty";
|
"Config data is empty";
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xbc_data = memblock_alloc(size + 1, SMP_CACHE_BYTES);
|
||||||
|
if (!xbc_data) {
|
||||||
|
if (emsg)
|
||||||
|
*emsg = "Failed to allocate bootconfig data";
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(xbc_data, data, size);
|
||||||
|
xbc_data[size] = '\0';
|
||||||
|
xbc_data_size = size + 1;
|
||||||
|
|
||||||
xbc_nodes = memblock_alloc(sizeof(struct xbc_node) * XBC_NODE_MAX,
|
xbc_nodes = memblock_alloc(sizeof(struct xbc_node) * XBC_NODE_MAX,
|
||||||
SMP_CACHE_BYTES);
|
SMP_CACHE_BYTES);
|
||||||
if (!xbc_nodes) {
|
if (!xbc_nodes) {
|
||||||
if (emsg)
|
if (emsg)
|
||||||
*emsg = "Failed to allocate bootconfig nodes";
|
*emsg = "Failed to allocate bootconfig nodes";
|
||||||
|
xbc_destroy_all();
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX);
|
memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX);
|
||||||
xbc_data = buf;
|
|
||||||
xbc_data_size = ret + 1;
|
|
||||||
last_parent = NULL;
|
|
||||||
|
|
||||||
p = buf;
|
last_parent = NULL;
|
||||||
|
p = xbc_data;
|
||||||
do {
|
do {
|
||||||
q = strpbrk(p, "{}=+;:\n#");
|
q = strpbrk(p, "{}=+;:\n#");
|
||||||
if (!q) {
|
if (!q) {
|
||||||
|
|
|
@ -229,7 +229,7 @@ static int load_xbc_from_initrd(int fd, char **buf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = xbc_init(*buf, &msg, NULL);
|
ret = xbc_init(*buf, size, &msg, NULL);
|
||||||
/* Wrong data */
|
/* Wrong data */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("parse error: %s.\n", msg);
|
pr_err("parse error: %s.\n", msg);
|
||||||
|
@ -269,7 +269,7 @@ static int init_xbc_with_error(char *buf, int len)
|
||||||
if (!copy)
|
if (!copy)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = xbc_init(buf, &msg, &pos);
|
ret = xbc_init(buf, len, &msg, &pos);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
show_xbc_error(copy, msg, pos);
|
show_xbc_error(copy, msg, pos);
|
||||||
free(copy);
|
free(copy);
|
||||||
|
@ -382,7 +382,7 @@ static int apply_xbc(const char *path, const char *xbc_path)
|
||||||
memcpy(data, buf, size);
|
memcpy(data, buf, size);
|
||||||
|
|
||||||
/* Check the data format */
|
/* Check the data format */
|
||||||
ret = xbc_init(buf, &msg, &pos);
|
ret = xbc_init(buf, size, &msg, &pos);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
show_xbc_error(data, msg, pos);
|
show_xbc_error(data, msg, pos);
|
||||||
free(data);
|
free(data);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче