The current implementation of raw_copy_guest helper may lead to data corruption
and sometimes Xen crash when the guest virtual address is not aligned to
PAGE_SIZE.
When the total length is higher than a page, the length to read is badly
compute with
min(len, (unsigned)(PAGE_SIZE - offset))
As the offset is only computed one time per function, if the start address was
not aligned to PAGE_SIZE, we can end up in same iteration:
- to read accross page boundary => xen crash
- read the previous page => data corruption
This issue can be resolved by setting offset to 0 at the end of the first
iteration. Indeed, after it, the virtual guest address is always aligned
to PAGE_SIZE.
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: George Dunlap <george.dunlap@citrix.com>
[ ijc -- duplicated the comment in the other two functions with this behaviour ]
len -= size;
from += size;
to += size;
+ /*
+ * After the first iteration, guest virtual address is correctly
+ * aligned to PAGE_SIZE.
+ */
offset = 0;
}
unmap_domain_page(p - offset);
len -= size;
to += size;
+ /*
+ * After the first iteration, guest virtual address is correctly
+ * aligned to PAGE_SIZE.
+ */
offset = 0;
}
len -= size;
from += size;
to += size;
+ /*
+ * After the first iteration, guest virtual address is correctly
+ * aligned to PAGE_SIZE.
+ */
+ offset = 0;
}
return 0;
}