From: "Michael S. Tsirkin" <mst@redhat.com>
To: Thomas Huth <thuth@redhat.com>
Cc: "Clément MATHIEU--DRIF" <clement.mathieu--drif@bull.com>,
"Peter Xu" <peterx@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"Yi Liu" <yi.l.liu@intel.com>
Subject: Re: intel_iommu unit test is also failing
Date: Tue, 5 May 2026 06:23:45 -0400 [thread overview]
Message-ID: <20260505061927-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <6b338140-873c-4303-bdd1-633d69f4a971@redhat.com>
On Tue, May 05, 2026 at 11:45:17AM +0200, Thomas Huth wrote:
> On 05/05/2026 11.27, Clément MATHIEU--DRIF wrote:
> > I had a bit more time to hook into qemu to check the root cause.
> >
> > It seems that testb issues a single byte read (out of the valid size range), as we can see on the following breakpoint:
> >
> > ```
> > Thread 6 "CPU 0/TCG" hit Breakpoint 2, memory_region_dispatch_read (mr=0x55d72883cb30, addr=152, pval=0x7f62d25f4590, op=MO_BSWAP, attrs=...) at ../system/memory.c:1473
> > 1473 unsigned size = memop_size(op);
> > (gdb) n
> > 1474 MemTxResult r;
> > (gdb) p size
> > $1 = 1
> > (gdb)
> > ```
>
> Ouch! That's an excellent finding, Clément ... so GCC 16 is "smart" enough
> to see that we only want to test the lowest bit here, so it optimizes the
> code to access only one byte of memory instead of 4 bytes... which would be
> ok for normal memory, but not for an MMIO register :-/
>
> Ugly work-around, to force GCC to read 32 bits:
>
> diff --git a/lib/asm-generic/io.h b/lib/asm-generic/io.h
> --- a/lib/asm-generic/io.h
> +++ b/lib/asm-generic/io.h
> @@ -38,7 +38,9 @@ static inline u16 __raw_readw(const volatile void *addr)
> #ifndef __raw_readl
> static inline u32 __raw_readl(const volatile void *addr)
> {
> - return *(const volatile u32 *)addr;
> + u32 val = *(const volatile u32 *)addr;
> + asm volatile ("\n" : : "r"(addr));
> + return val;
> }
> #endif
>
> ... but I wonder whether this should rather be treated as a bug in GCC
> instead, since it should IMHO really not change the access size for a
> volatile memory access?
>
> Thomas
Wouldn't this break linux generally?
#ifndef __READ_ONCE
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
#endif
>
> > cmd
> >
> > On Tue, 2026-05-05 at 09:36 +0200, Clement Mathieu--Drif wrote:
> > > Back with some answers:
> > >
> > > This is the incriminated hunk:
> > >
> > > ```diff
> > > --- <unnamed>
> > > +++ <unnamed>
> > > @@ -1,17 +1,16 @@
> > > - 404395: 8b 80 98 00 00 00 mov 0x98(%eax),%eax
> > > + 40441d: 8b 43 38 mov 0x38(%ebx),%eax
> > > edu_reg_writeq(dev, EDU_REG_DMA_DST, to);
> > > edu_reg_writeq(dev, EDU_REG_DMA_COUNT, size);
> > > edu_reg_writel(dev, EDU_REG_DMA_CMD, cmd);
> > >
> > > /* Wait until DMA finished */
> > > while (edu_reg_readl(dev, EDU_REG_DMA_CMD) & EDU_CMD_DMA_START)
> > > - 40439b: a8 01 test $0x1,%al
> > > - 40439d: 74 10 je 4043af <edu_dma+0x121>
> > > - 40439f: f3 90 pause
> > > - 4043a1: 48 dec %eax
> > > - 4043a2: 8b 43 38 mov 0x38(%ebx),%eax
> > > - 4043a5: 8b 80 98 00 00 00 mov 0x98(%eax),%eax
> > > - 4043ab: a8 01 test $0x1,%al
> > > - 4043ad: 75 f0 jne 40439f <edu_dma+0x111>
> > > + 404420: f6 80 98 00 00 00 01 testb $0x1,0x98(%eax)
> > > + 404427: 74 0f je 404438 <edu_dma+0x11f>
> > > + 404429: f3 90 pause
> > > + 40442b: 48 dec %eax
> > > + 40442c: 8b 43 38 mov 0x38(%ebx),%eax
> > > + 40442f: f6 80 98 00 00 00 01 testb $0x1,0x98(%eax)
> > > + 404436: 75 f1 jne 404429 <edu_dma+0x110>
> > > cpu_relax();
> > > }
> > >
> > > + is gcc 16
> > > - is gcc 15
> > >
> > > The instructions generated by gcc 16 always skip the following condition:
> > >
> > > ```
> > > /* Wait until DMA finished */
> > > while (edu_reg_readl(dev, EDU_REG_DMA_CMD) & EDU_CMD_DMA_START)
> > > cpu_relax();
> > > ```
> > >
> > > As a consequence, the test performs the second dma operation too early and reads a wrong value.
> > >
> > > Regards,
> > > cmd
next prev parent reply other threads:[~2026-05-05 10:23 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-04 14:35 [PATCH kvm-unit-tests] realmode: load above stack Paolo Bonzini
2024-06-04 14:40 ` Thomas Huth
2024-06-04 14:50 ` Paolo Bonzini
2026-05-04 7:58 ` Thomas Huth
2026-05-04 8:07 ` intel_iommu unit test is also failing (was: Re: [PATCH kvm-unit-tests] realmode: load above stack) Thomas Huth
2026-05-04 15:45 ` Peter Xu
2026-05-05 5:49 ` Clément MATHIEU--DRIF
2026-05-05 6:37 ` Clément MATHIEU--DRIF
2026-05-05 7:36 ` Clément MATHIEU--DRIF
2026-05-05 9:27 ` Clément MATHIEU--DRIF
2026-05-05 9:45 ` intel_iommu unit test is also failing Thomas Huth
2026-05-05 9:53 ` Clément MATHIEU--DRIF
2026-05-05 10:15 ` Thomas Huth
2026-05-05 10:23 ` Michael S. Tsirkin [this message]
2026-05-05 10:34 ` Thomas Huth
2026-05-05 10:53 ` Michael S. Tsirkin
2026-05-05 11:38 ` Thomas Huth
2026-05-05 12:33 ` Michael S. Tsirkin
2026-05-05 17:08 ` Thomas Huth
2026-05-05 11:39 ` Clément MATHIEU--DRIF
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=20260505061927-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=clement.mathieu--drif@bull.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=thuth@redhat.com \
--cc=yi.l.liu@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.