From: David Hildenbrand <david@redhat.com>
To: qemu-devel@nongnu.org
Cc: Florian Weimer <fweimer@redhat.com>,
Thomas Huth <thuth@redhat.com>,
David Hildenbrand <david@redhat.com>,
Cornelia Huck <cohuck@redhat.com>,
Stefano Brivio <sbrivio@redhat.com>,
qemu-s390x@nongnu.org, Richard Henderson <rth@twiddle.net>
Subject: [Qemu-devel] [PATCH v1 4/4] s390x/tcg: MOVE (MVC): Fault-safe handling
Date: Wed, 21 Aug 2019 11:22:52 +0200 [thread overview]
Message-ID: <20190821092252.26541-5-david@redhat.com> (raw)
In-Reply-To: <20190821092252.26541-1-david@redhat.com>
MVC can cross page boundaries. In case we fault on the second page, we
already partially copied data. If we have overlaps, we would
trigger a fault after having partially moved data, eventually having
our original data already overwritten. When continuing after the fault,
we would try to move already modified data, not the original data -
very bad.
glibc started to use MVC for forward memmove() and is able to trigger
exectly this corruption (via rpmbuild and rpm). Fedora 31 (rawhide)
currently fails to install as we trigger rpm database corruptions due to
this bug.
Let's properly probe for read/write access in case we cross page
boundaries. In case we don't cross boundaries, the first accesses will
trigger the fault.
We'll have to do the same for other instructions (like MVCLE), too. But
the more I look at the other MOVE variantes the more issues I find, so
let's handle MVC for now only.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
target/s390x/mem_helper.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index bf7dfcdc7a..44001ec21a 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -104,6 +104,11 @@ static inline void cpu_stsize_data_ra(CPUS390XState *env, uint64_t addr,
}
}
+static inline bool is_single_page_access(uint64_t addr, uint32_t size)
+{
+ return (addr & TARGET_PAGE_MASK) == ((addr + size - 1) & TARGET_PAGE_MASK);
+}
+
static void fast_memset(CPUS390XState *env, uint64_t dest, uint8_t byte,
uint32_t l, uintptr_t ra)
{
@@ -310,6 +315,10 @@ static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest,
/* MVC always copies one more byte than specified - maximum is 256 */
l++;
+ if (unlikely(!is_single_page_access(dest, l))) {
+ probe_write_access(env, dest, l, ra);
+ }
+
/*
* "When the operands overlap, the result is obtained as if the operands
* were processed one byte at a time". Only non-overlapping or forward
@@ -317,7 +326,14 @@ static uint32_t do_helper_mvc(CPUS390XState *env, uint32_t l, uint64_t dest,
*/
if (dest == src + 1) {
fast_memset(env, dest, cpu_ldub_data_ra(env, src, ra), l, ra);
- } else if (dest < src || src + l <= dest) {
+ return env->cc_op;
+ }
+
+ if (unlikely(!is_single_page_access(src, l))) {
+ probe_read_access(env, src, l, ra);
+ }
+
+ if (dest < src || src + l <= dest) {
fast_memmove(env, dest, src, l, ra);
} else {
for (i = 0; i < l; i++) {
--
2.21.0
prev parent reply other threads:[~2019-08-21 9:26 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-21 9:22 [Qemu-devel] [PATCH v1 0/4] s390x/tcg: MOVE (MVC): Fault-safe handling David Hildenbrand
2019-08-21 9:22 ` [Qemu-devel] [PATCH v1 1/4] s390x/tcg: Use guest_addr_valid() instead of h2g_valid() in probe_write_access() David Hildenbrand
2019-08-21 9:22 ` [Qemu-devel] [PATCH v1 2/4] s390x/tcg: Introduce probe_read_access() David Hildenbrand
2019-08-21 17:26 ` Richard Henderson
2019-08-21 17:37 ` David Hildenbrand
2019-08-21 19:19 ` Richard Henderson
2019-08-21 19:36 ` David Hildenbrand
2019-08-21 20:38 ` Richard Henderson
2019-08-21 21:33 ` David Hildenbrand
2019-08-21 22:31 ` Richard Henderson
2019-08-21 22:43 ` Richard Henderson
2019-08-22 6:42 ` David Hildenbrand
2019-08-22 7:01 ` David Hildenbrand
2019-08-26 9:31 ` David Hildenbrand
2019-08-21 18:48 ` David Hildenbrand
2019-08-21 9:22 ` [Qemu-devel] [PATCH v1 3/4] s390x/tcg: MOVE (MVC): Increment the length once David Hildenbrand
2019-08-21 15:47 ` Richard Henderson
2019-08-21 9:22 ` David Hildenbrand [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190821092252.26541-5-david@redhat.com \
--to=david@redhat.com \
--cc=cohuck@redhat.com \
--cc=fweimer@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=rth@twiddle.net \
--cc=sbrivio@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).