Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: Thomas Huth <thuth@redhat.com>
To: "Clément MATHIEU--DRIF" <clement.mathieu--drif@bull.com>,
	"Peter Xu" <peterx@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	Yi Liu <yi.l.liu@intel.com>,
	"Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: intel_iommu unit test is also failing
Date: Tue, 5 May 2026 11:45:17 +0200	[thread overview]
Message-ID: <6b338140-873c-4303-bdd1-633d69f4a971@redhat.com> (raw)
In-Reply-To: <d4ae6782e30a05ea9d56c38f0c5d296fb6a5c7b1.camel@bull.com>

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


> 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


  reply	other threads:[~2026-05-05  9:45 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240604143507.1041901-1-pbonzini@redhat.com>
2026-05-04  7:58 ` [PATCH kvm-unit-tests] realmode: load above stack 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               ` Thomas Huth [this message]
2026-05-05  9:53                 ` intel_iommu unit test is also failing Clément MATHIEU--DRIF
2026-05-05 10:15                   ` Thomas Huth
2026-05-05 10:23                 ` Michael S. Tsirkin
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=6b338140-873c-4303-bdd1-633d69f4a971@redhat.com \
    --to=thuth@redhat.com \
    --cc=clement.mathieu--drif@bull.com \
    --cc=kvm@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox