From 589bbbeccdc574d4c964d3f404a2e0605a545a4e Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 17 Sep 2018 22:03:42 -0700 Subject: memtest: Adjust code for 64-bit architectures Make use of %pa specifier to avoid warnings when building against 64-bit CPU (specifically AArch64) as well as adjust a number of patterns to be 64-bits wide. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- common/memtest.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'common') diff --git a/common/memtest.c b/common/memtest.c index 0fc2046758..5c96d46e9a 100644 --- a/common/memtest.c +++ b/common/memtest.c @@ -160,24 +160,29 @@ static void mem_test_report_failure(const char *failure_description, resource_size_t actual_value, volatile resource_size_t *address) { + /* + * expected_value and actual_value below are not really + * pointers, but we want them to be printed exactly the same + * as pointers would, so we use %pa regardless + */ printf("FAILURE (%s): " - "expected 0x%08x, actual 0x%08x at address 0x%08x.\n", - failure_description, expected_value, actual_value, - (resource_size_t)address); + "expected %pa, actual %pa at address %pa.\n", + failure_description, &expected_value, &actual_value, + &address); } int mem_test_bus_integrity(resource_size_t _start, resource_size_t _end) { - static const resource_size_t bitpattern[] = { - 0x00000001, /* single bit */ - 0x00000003, /* two adjacent bits */ - 0x00000007, /* three adjacent bits */ - 0x0000000F, /* four adjacent bits */ - 0x00000005, /* two non-adjacent bits */ - 0x00000015, /* three non-adjacent bits */ - 0x00000055, /* four non-adjacent bits */ - 0xAAAAAAAA, /* alternating 1/0 */ + static const uint64_t bitpattern[] = { + 0x0000000000000001ULL, /* single bit */ + 0x0000000000000003ULL, /* two adjacent bits */ + 0x0000000000000007ULL, /* three adjacent bits */ + 0x000000000000000FULL, /* four adjacent bits */ + 0x0000000000000005ULL, /* two non-adjacent bits */ + 0x0000000000000015ULL, /* three non-adjacent bits */ + 0x0000000000000055ULL, /* four non-adjacent bits */ + 0xAAAAAAAAAAAAAAAAULL, /* alternating 1/0 */ }; volatile resource_size_t *start, *dummy, num_words, val, readback, offset, @@ -217,7 +222,7 @@ int mem_test_bus_integrity(resource_size_t _start, * pattern and ~pattern). */ for (i = 0; i < ARRAY_SIZE(bitpattern); i++) { - val = bitpattern[i]; + val = (resource_size_t)bitpattern[i]; for (; val != 0; val <<= 1) { *start = val; @@ -282,8 +287,8 @@ int mem_test_bus_integrity(resource_size_t _start, * 01ffffff is perfect. */ - pattern = 0xAAAAAAAA; - anti_pattern = 0x55555555; + pattern = (resource_size_t)0xAAAAAAAAAAAAAAAAULL; + anti_pattern = (resource_size_t)0x5555555555555555ULL; /* * Write the default pattern at each of the -- cgit v1.2.3 From 5e131c5905265c2060836864557fe51198627dea Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 17 Sep 2018 22:03:43 -0700 Subject: memtest: Make use of resource_size() Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- commands/memtest.c | 3 +-- common/memtest.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'common') diff --git a/commands/memtest.c b/commands/memtest.c index 403ab91f6f..dc8f7db279 100644 --- a/commands/memtest.c +++ b/commands/memtest.c @@ -36,8 +36,7 @@ static int do_test_one_area(struct mem_test_resource *r, int bus_only, printf("Testing memory space: %pa -> %pa:\n", &r->r->start, &r->r->end); - remap_range((void *)r->r->start, r->r->end - - r->r->start + 1, cache_flag); + remap_range((void *)r->r->start, resource_size(r->r), cache_flag); ret = mem_test_bus_integrity(r->r->start, r->r->end); if (ret < 0) diff --git a/common/memtest.c b/common/memtest.c index 5c96d46e9a..44ddedd3d4 100644 --- a/common/memtest.c +++ b/common/memtest.c @@ -131,8 +131,8 @@ void mem_test_release_regions(struct list_head *list) /* * Ensure to leave with a cached on non used sdram regions. */ - remap_range((void *)r->r->start, r->r->end - - r->r->start + 1, MAP_DEFAULT); + remap_range((void *)r->r->start, resource_size(r->r), + MAP_DEFAULT); release_sdram_region(r->r); free(r); -- cgit v1.2.3 From c6bdbf6e93a11227f91fbf15b7a36dceb60c526d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2018 14:18:33 +0200 Subject: environment: Allow default env path to be NULL Several places assume that the default environment path cannot be NULL. Allow NULL here without crashing. Signed-off-by: Sascha Hauer --- commands/loadenv.c | 4 ++++ common/environment.c | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/commands/loadenv.c b/commands/loadenv.c index 6469affadb..bf01072c42 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -61,6 +61,10 @@ static int do_loadenv(int argc, char *argv[]) if (argc - optind < 1) { filename = default_environment_path_get(); + if (!filename) { + printf("Default environment path not set\n"); + return 1; + } } else { /* * /dev/defaultenv use to contain the defaultenvironment. diff --git a/common/environment.c b/common/environment.c index 0edf34b661..56a030eda0 100644 --- a/common/environment.c +++ b/common/environment.c @@ -256,9 +256,12 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) struct action_data data = {}; void *buf = NULL, *wbuf; struct envfs_entry *env; + const char *defenv_path = default_environment_path_get(); if (!filename) - filename = default_environment_path_get(); + filename = defenv_path; + if (!filename) + return -ENOENT; if (!dirname) dirname = "/env"; @@ -365,7 +368,7 @@ int envfs_save(const char *filename, const char *dirname, unsigned flags) ret = 0; #ifdef CONFIG_NVVAR - if (!strcmp(filename, default_environment_path_get())) + if (defenv_path && !strcmp(filename, defenv_path)) nv_var_set_clean(); #endif out: @@ -558,6 +561,8 @@ int envfs_load(const char *filename, const char *dir, unsigned flags) if (!filename) filename = default_environment_path_get(); + if (!filename) + return -ENOENT; if (!dir) dir = "/env"; -- cgit v1.2.3 From b234a6da331fa9ec656f2d278adafdeea45f9073 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 21 Sep 2018 14:21:14 +0200 Subject: environment: Do not use environment when overlapping with other partitions Environment partitions are usually specified with their hardcoded offset and size, either in the device tree or the board file. These partitions potentially overlap with other partitions read from the partition table. Overlapping partitions for sure have bad effects. Be more friendly to our users and warn them when such a situation occurs and stop using that partition for storing the environment. Signed-off-by: Sascha Hauer --- common/startup.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- include/common.h | 10 ++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) (limited to 'common') diff --git a/common/startup.c b/common/startup.c index 8553849cb3..832d3262fe 100644 --- a/common/startup.c +++ b/common/startup.c @@ -73,16 +73,66 @@ fs_initcall(mount_root); #endif #ifdef CONFIG_ENV_HANDLING +static int check_overlap(const char *path) +{ + struct cdev *cenv, *cdisk, *cpart; + const char *name; + + name = devpath_to_name(path); + + if (name == path) + /* + * no /dev/ in front, so *path is some file. No need to + * check further. + */ + return 0; + + cenv = cdev_by_name(name); + if (!cenv) + return -EINVAL; + + cdisk = cenv->master; + + if (!cdisk) + return 0; + + list_for_each_entry(cpart, &cdisk->partitions, partition_entry) { + if (cpart == cenv) + continue; + + if (lregion_overlap(cpart->offset, cpart->size, + cenv->offset, cenv->size)) + goto conflict; + } + + return 0; + +conflict: + pr_err("Environment partition (0x%08llx-0x%08llx) " + "overlaps with partition %s (0x%08llx-0x%08llx), not using it\n", + cenv->offset, cenv->offset + cenv->offset + cenv->size - 1, + cpart->name, + cpart->offset, cpart->offset + cpart->offset + cpart->size - 1); + + return -EINVAL; +} + static int load_environment(void) { const char *default_environment_path; + int ret; default_environment_path = default_environment_path_get(); if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) defaultenv_load("/env", 0); - envfs_load(default_environment_path, "/env", 0); + ret = check_overlap(default_environment_path); + if (ret) + default_environment_path_set(NULL); + else + envfs_load(default_environment_path, "/env", 0); + nvvar_load(); return 0; diff --git a/include/common.h b/include/common.h index abbe73fd36..f52c7e430c 100644 --- a/include/common.h +++ b/include/common.h @@ -157,4 +157,14 @@ static inline bool region_overlap(unsigned long starta, unsigned long lena, return 1; } +static inline bool lregion_overlap(loff_t starta, loff_t lena, + loff_t startb, loff_t lenb) +{ + if (starta + lena <= startb) + return 0; + if (startb + lenb <= starta) + return 0; + return 1; +} + #endif /* __COMMON_H_ */ -- cgit v1.2.3