qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] target/s390x: Fix translation exception on illegal instru


From: David Hildenbrand
Subject: Re: [PATCH v2] target/s390x: Fix translation exception on illegal instruction
Date: Wed, 14 Apr 2021 09:34:22 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1

On 13.04.21 18:52, Ilya Leoshkevich wrote:
Hitting an uretprobe in a s390x TCG guest causes a SIGSEGV. What
happens is:

* uretprobe maps a userspace page containing an invalid instruction.
* uretprobe replaces the target function's return address with the
   address of that page.
* When tb_gen_code() is called on that page, tb->size ends up being 0
   (because the page starts with the invalid instruction), which causes
   virt_page2 to point to the previous page.
* The previous page is not mapped, so this causes a spurious
   translation exception.

The bug is that tb->size must never be 0: even if there is an illegal
instruction, the instruction bytes that have been looked at must count
towards tb->size. So adjust s390x's translate_one() to act this way
for both illegal instructions and instructions that are known to
generate exceptions.

Also add an assertion to tb_gen_code() in order to detect such
situations in future.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---

v1: https://lists.nongnu.org/archive/html/qemu-devel/2021-04/msg02037.html
v1 -> v2: Fix target/s390x instead of trying to tolerate tb->size == 0
           in tb_gen_code().

  accel/tcg/translate-all.c |  1 +
  target/s390x/translate.c  | 16 +++++++++++-----
  2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index ba6ab09790..93b2dae112 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1913,6 +1913,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
tcg_ctx->cpu = env_cpu(env);
      gen_intermediate_code(cpu, tb, max_insns);
+    assert(tb->size != 0);
      tcg_ctx->cpu = NULL;
      max_insns = tb->icount;
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 4f953ddfba..e243624d2a 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -6412,7 +6412,8 @@ static DisasJumpType translate_one(CPUS390XState *env, 
DisasContext *s)
          qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
                        s->fields.op, s->fields.op2);
          gen_illegal_opcode(s);
-        return DISAS_NORETURN;
+        ret = DISAS_NORETURN;
+        goto out;
      }
#ifndef CONFIG_USER_ONLY
@@ -6428,7 +6429,8 @@ static DisasJumpType translate_one(CPUS390XState *env, 
DisasContext *s)
          /* privileged instruction */
          if ((s->base.tb->flags & FLAG_MASK_PSTATE) && (insn->flags & 
IF_PRIV)) {
              gen_program_exception(s, PGM_PRIVILEGED);
-            return DISAS_NORETURN;
+            ret = DISAS_NORETURN;
+            goto out;
          }
/* if AFP is not enabled, instructions and registers are forbidden */
@@ -6455,7 +6457,8 @@ static DisasJumpType translate_one(CPUS390XState *env, 
DisasContext *s)
              }
              if (dxc) {
                  gen_data_exception(dxc);
-                return DISAS_NORETURN;
+                ret = DISAS_NORETURN;
+                goto out;
              }
          }
@@ -6463,7 +6466,8 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
          if (insn->flags & IF_VEC) {
              if (!((s->base.tb->flags & FLAG_MASK_VECTOR))) {
                  gen_data_exception(0xfe);
-                return DISAS_NORETURN;
+                ret = DISAS_NORETURN;
+                goto out;
              }
          }
@@ -6484,7 +6488,8 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
              (insn->spec & SPEC_r1_f128 && !is_fp_pair(get_field(s, r1))) ||
              (insn->spec & SPEC_r2_f128 && !is_fp_pair(get_field(s, r2)))) {
              gen_program_exception(s, PGM_SPECIFICATION);
-            return DISAS_NORETURN;
+            ret = DISAS_NORETURN;
+            goto out;
          }
      }
@@ -6544,6 +6549,7 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
      }
  #endif
+out:
      /* Advance to the next instruction.  */
      s->base.pc_next = s->pc_tmp;
      return ret;


Reviewed-by: David Hildenbrand <david@redhat.com>

--
Thanks,

David / dhildenb




reply via email to

[Prev in Thread] Current Thread [Next in Thread]