| @@ -61,9 +61,12 @@ static inline void * __init xbc_alloc_mem(size_t size) · 60 unmodified lines |
| 61 | 61 | return memblock_alloc(size, SMP_CACHE_BYTES); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | | −static inline void __init xbc_free_mem(void *addr, size_t size) |
| 64 | +static inline void __init xbc_free_mem(void *addr, size_t size, bool early) |
| 65 | 65 | { |
| 66 | | − memblock_free(addr, size); |
| 66 | + if (early) |
| 67 | + memblock_free(addr, size); |
| 68 | + else if (addr) |
| 69 | + memblock_free_late(__pa(addr), size); |
| 67 | 70 | } |
| 68 | 71 | |
| 69 | 72 | #else /* !__KERNEL__ */ |
| @@ -73,7 +76,7 @@ static inline void *xbc_alloc_mem(size_t size) · 3 unmodified lines |
| 73 | 76 | return malloc(size); |
| 74 | 77 | } |
| 75 | 78 | |
| 76 | | −static inline void xbc_free_mem(void *addr, size_t size) |
| 79 | +static inline void xbc_free_mem(void *addr, size_t size, bool early) |
| 77 | 80 | { |
| 78 | 81 | free(addr); |
| 79 | 82 | } |
| @@ -898,19 +901,20 @@ static int __init xbc_parse_tree(void) · 818 unmodified lines |
| 898 | 901 | } |
| 899 | 902 | |
| 900 | 903 | /** |
| 901 | | − * xbc_exit() - Clean up all parsed bootconfig |
| 904 | + * _xbc_exit() - Clean up all parsed bootconfig |
| 905 | + * @early: Set true if this is called before budy system is initialized. |
| 902 | 906 | * |
| 903 | 907 | * This clears all data structures of parsed bootconfig on memory. |
| 904 | 908 | * If you need to reuse xbc_init() with new boot config, you can |
| 905 | 909 | * use this. |
| 906 | 910 | */ |
| 907 | | −void __init xbc_exit(void) |
| 911 | +void __init _xbc_exit(bool early) |
| 908 | 912 | { |
| 909 | | − xbc_free_mem(xbc_data, xbc_data_size); |
| 913 | + xbc_free_mem(xbc_data, xbc_data_size, early); |
| 910 | 914 | xbc_data = NULL; |
| 911 | 915 | xbc_data_size = 0; |
| 912 | 916 | xbc_node_num = 0; |
| 913 | | − xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX); |
| 917 | + xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX, early); |
| 914 | 918 | xbc_nodes = NULL; |
| 915 | 919 | brace_index = 0; |
| 916 | 920 | } |
| @@ -963,7 +967,7 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) · 46 unmodified lines |
| 963 | 967 | if (!xbc_nodes) { |
| 964 | 968 | if (emsg) |
| 965 | 969 | *emsg = "Failed to allocate bootconfig nodes"; |
| 966 | | − xbc_exit(); |
| 970 | + _xbc_exit(true); |
| 967 | 971 | return -ENOMEM; |
| 968 | 972 | } |
| 969 | 973 | memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX); |
| @@ -977,7 +981,7 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) · 7 unmodified lines |
| 977 | 981 | *epos = xbc_err_pos; |
| 978 | 982 | if (emsg) |
| 979 | 983 | *emsg = xbc_err_msg; |
| 980 | | − xbc_exit(); |
| 984 | + _xbc_exit(true); |
| 981 | 985 | } else |
| 982 | 986 | ret = xbc_node_num; |
| 983 | 987 | |