summaryrefslogtreecommitdiff
path: root/common/image.c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2014-12-10 18:20:53 +0800
committerTom Rini <trini@ti.com>2015-01-05 16:40:19 -0500
commit22cfddc2a0343cdbef7f1263830c2dacaa75f22e (patch)
treeea6070f8d43b7fe181e5046005da58d86379cc5e /common/image.c
parenteb54d2c70ce3b14e0c9ae141e216d5ad0b22d0dd (diff)
downloadu-boot-imx-22cfddc2a0343cdbef7f1263830c2dacaa75f22e.zip
u-boot-imx-22cfddc2a0343cdbef7f1263830c2dacaa75f22e.tar.gz
u-boot-imx-22cfddc2a0343cdbef7f1263830c2dacaa75f22e.tar.bz2
memmove_wd: copy chunk down from big address if parameter to is larger than from
When watchdog is enabled, memmove_wd() always copy chunk up from small address. This damanges overlapped memory data if destination address is smaller than source address. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/image.c')
-rw-r--r--common/image.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/common/image.c b/common/image.c
index b75a5ce..e691a51 100644
--- a/common/image.c
+++ b/common/image.c
@@ -485,12 +485,22 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz)
return;
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+ if (to > from) {
+ from += len;
+ to += len;
+ }
while (len > 0) {
size_t tail = (len > chunksz) ? chunksz : len;
WATCHDOG_RESET();
+ if (to > from) {
+ to -= tail;
+ from -= tail;
+ }
memmove(to, from, tail);
- to += tail;
- from += tail;
+ if (to < from) {
+ to += tail;
+ from += tail;
+ }
len -= tail;
}
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */