On Thu, Jul 24, 2025 at 03:50:36PM -0700, Eric Biggers wrote:
> Another QEMU bug found by the Linux kernel's crypto tests
> (https://lore.kernel.org/linux-crypto/20250724173657.GB26800@sol/):
>
> When KVM is disabled, QEMU's implementation of the AVX2 instruction
> 'vinserti128' with a memory source operand incorrectly reads 32 bytes
> from memory. This differs from the real CPUs which read only 16 bytes,
> as per the spec
> (https://www.felixcloutier.com/x86/vinserti128:vinserti32x4:vinserti64x2:vinserti32x8:vinserti64x4)
> which defines the operand as xmm3/m128.
>
> This can be reproduced by the recently-added poly1305_kunit test in
> linux-next, or alternatively by the following userspace program:
>
> #include <stddef.h>
> #include <sys/mman.h>
> int main()
> {
> unsigned char *buf = mmap(NULL, 8192, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
>
> munmap(buf + 4096, 4096);
> asm volatile("vinserti128 $1, %0, %%ymm0, %%ymm0\n"
> :: "m" (buf[4080]));
> }
>
> That executes vinserti128 with a memory operand with 16 valid bytes
> followed by an unmapped page. This works fine on the real CPUs, but it
> segfaults when run with qemu-x86_64. To avoid the segfault in QEMU, we
> have to go down to buf[4064], which implies it reads 32 bytes.
>
> This bug exists on the master branch of QEMU as well as v8.2.10 and
> v7.2.19. So probably it's not new.
>
> - Eric
It looks like support for this instruction was added by the following
commit:
commit 7906847768613ea6b6e737f3295c77cdb4ff67f4
Author: Paolo Bonzini <[email protected]>
Date: Tue Sep 6 10:34:11 2022 +0200
target/i387: reimplement 0x0f 0x3a, add AVX