diff mbox series

[PULL,30/33] tcg: Allocate sufficient storage in temp_allocate_frame

Message ID 20210619181452.877683-31-richard.henderson@linaro.org
State New
Headers show
Series [PULL,01/33] tcg: Combine dh_is_64bit and dh_is_signed to dh_typecode | expand

Commit Message

Richard Henderson June 19, 2021, 6:14 p.m. UTC
This function should have been updated for vector types
when they were introduced.

Fixes: d2fd745fe8b
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/367
Cc: qemu-stable@nongnu.org
Tested-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/tcg.c | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

Comments

Richard W.M. Jones Sept. 1, 2021, 10:52 a.m. UTC | #1
On Sat, Jun 19, 2021 at 11:14:49AM -0700, Richard Henderson wrote:
> This function should have been updated for vector types
> when they were introduced.
> 
> Fixes: d2fd745fe8b
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/367
> Cc: qemu-stable@nongnu.org
> Tested-by: Stefan Weil <sw@weilnetz.de>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  tcg/tcg.c | 32 +++++++++++++++++++++++++++-----
>  1 file changed, 27 insertions(+), 5 deletions(-)
> 
...
> +    assert(align <= TCG_TARGET_STACK_ALIGN);

This assertion is triggering:
https://bugzilla.redhat.com/show_bug.cgi?id=1999878

It happens when the kernel is booting after this line:

  [    7.315373] Loading compiled-in X.509 certificates

If everything was working then the next line of output *should* be:

  Loaded X.509 cert 'Fedora kernel signing key: 65d4930f94e951d5c1531017b9559872a4e7b0b0'

but instead it is:

  [    7.183521] ThumbEE CPU extension supported.
  [    7.186066] Registering SWP/SWPB emulation handler
  [    7.304374] registered taskstats version 1
  [    7.315373] Loading compiled-in X.509 certificates
  qemu-system-arm: ../tcg/tcg.c:3063: temp_allocate_frame: Assertion `align <= TCG_TARGET_STACK_ALIGN' failed.

Unfortunately I don't have an easy reproducer.  It reproduces very
reliably in Fedora's build system (qemu 6.1.0 running a TCG armv7 L2
guest on armv7 L1 host on unknown aarch64 L0 host).  But my attempts
to perform the same operation anywhere else don't reproduce the
problem.

What does the assertion mean?

Rich.
Daniel P. Berrangé Sept. 1, 2021, 12:55 p.m. UTC | #2
On Wed, Sep 01, 2021 at 11:52:31AM +0100, Richard W.M. Jones wrote:
> On Sat, Jun 19, 2021 at 11:14:49AM -0700, Richard Henderson wrote:
> > This function should have been updated for vector types
> > when they were introduced.
> > 
> > Fixes: d2fd745fe8b
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/367
> > Cc: qemu-stable@nongnu.org
> > Tested-by: Stefan Weil <sw@weilnetz.de>
> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> >  tcg/tcg.c | 32 +++++++++++++++++++++++++++-----
> >  1 file changed, 27 insertions(+), 5 deletions(-)
> > 
> ...
> > +    assert(align <= TCG_TARGET_STACK_ALIGN);
> 
> This assertion is triggering:
> https://bugzilla.redhat.com/show_bug.cgi?id=1999878
> 
> It happens when the kernel is booting after this line:
> 
>   [    7.315373] Loading compiled-in X.509 certificates
> 
> If everything was working then the next line of output *should* be:
> 
>   Loaded X.509 cert 'Fedora kernel signing key: 65d4930f94e951d5c1531017b9559872a4e7b0b0'
> 
> but instead it is:
> 
>   [    7.183521] ThumbEE CPU extension supported.
>   [    7.186066] Registering SWP/SWPB emulation handler
>   [    7.304374] registered taskstats version 1
>   [    7.315373] Loading compiled-in X.509 certificates
>   qemu-system-arm: ../tcg/tcg.c:3063: temp_allocate_frame: Assertion `align <= TCG_TARGET_STACK_ALIGN' failed.
> 
> Unfortunately I don't have an easy reproducer.  It reproduces very
> reliably in Fedora's build system (qemu 6.1.0 running a TCG armv7 L2
> guest on armv7 L1 host on unknown aarch64 L0 host).  But my attempts
> to perform the same operation anywhere else don't reproduce the
> problem.
> 
> What does the assertion mean?

For arm we can see the TCG_TARGET_STACK_ALIGN value is 8:

  $ git grep TARGET_STACK_ALIGN | grep define | grep arm
  tcg/arm/tcg-target.h:#define TCG_TARGET_STACK_ALIGN		8

The value of 'align' can be larger than that though:

    switch (ts->type) {
    case TCG_TYPE_I32:
        size = align = 4;
        break;
    case TCG_TYPE_I64:
    case TCG_TYPE_V64:
        size = align = 8;
        break;
    case TCG_TYPE_V128:
        size = align = 16;
        break;
    case TCG_TYPE_V256:
        /* Note that we do not require aligned storage for V256. */
        size = 32, align = 16;

So something in TCG arm host/guest is triggering usage
of TCG_TYPE_V128 or TCG_TYPE_V256 types, and thus violating
the assert.

Either the assert is bogus, or TCG arm host/guest should not
be using those types that imply 16 byte alignment.

Regards,
Daniel
diff mbox series

Patch

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 52e858523c..47cc66f159 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -3015,17 +3015,39 @@  static void check_regs(TCGContext *s)
 
 static void temp_allocate_frame(TCGContext *s, TCGTemp *ts)
 {
-    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
-        s->frame_end) {
-        tcg_abort();
+    size_t size, align;
+    intptr_t off;
+
+    switch (ts->type) {
+    case TCG_TYPE_I32:
+        size = align = 4;
+        break;
+    case TCG_TYPE_I64:
+    case TCG_TYPE_V64:
+        size = align = 8;
+        break;
+    case TCG_TYPE_V128:
+        size = align = 16;
+        break;
+    case TCG_TYPE_V256:
+        /* Note that we do not require aligned storage for V256. */
+        size = 32, align = 16;
+        break;
+    default:
+        g_assert_not_reached();
     }
-    ts->mem_offset = s->current_frame_offset;
+
+    assert(align <= TCG_TARGET_STACK_ALIGN);
+    off = ROUND_UP(s->current_frame_offset, align);
+    assert(off + size <= s->frame_end);
+    s->current_frame_offset = off + size;
+
+    ts->mem_offset = off;
 #if defined(__sparc__)
     ts->mem_offset += TCG_TARGET_STACK_BIAS;
 #endif
     ts->mem_base = s->frame_temp;
     ts->mem_allocated = 1;
-    s->current_frame_offset += sizeof(tcg_target_long);
 }
 
 static void temp_load(TCGContext *, TCGTemp *, TCGRegSet, TCGRegSet, TCGRegSet);