While both src and dst are similar, src is mapped only accounting for src's
size, while dst is mapped based on the minimum of both. This means that in
some cases, an overly large mapping is requested for src.
Rework the sz calcuation to be symmetric, and leave an explanation of how
logic works.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Daniel P. Smith <dpsmith@apertussolutions.com>
And as if by magic, all transient fields from converting module_t are gone,
with bloat-o-meter reporting:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-74 (-74)
Function old new delta
move_memory 265 191 -74
which is all removal of logic inside the while loop.
---
xen/arch/x86/setup.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 152cd696d6c2..bb525980cdd8 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -492,23 +492,22 @@ static void __init noinline move_memory(
while ( size )
{
- unsigned int end /* mapsz */;
unsigned int soffs = src & mask;
unsigned int doffs = dst & mask;
unsigned int sz;
void *d, *s;
- end = soffs + size;
- if ( end > blksz )
- end = blksz;
- sz = end - soffs;
- s = bootstrap_map_addr(src, src + sz);
+ /*
+ * We're copying between two arbitrary buffers, as they fall within
+ * 2M-aligned regions with a maximum bound of blksz.
+ *
+ * For [ds]offs + size <= blksz, sz = size.
+ * For [ds]offs + size > blksz, sz = blksz - [ds]offs.
+ */
+ sz = max(soffs, doffs);
+ sz = min(sz + size, blksz) - sz;
- end = doffs + size;
- if ( end > blksz )
- end = blksz;
- if ( sz > end - doffs )
- sz = end - doffs;
+ s = bootstrap_map_addr(src, src + sz);
d = bootstrap_map_addr(dst, dst + sz);
memmove(d, s, sz);
--
2.39.5