* [QEMU bug] [x86_64] Incorrect emulation of vinserti128 instruction
@ 2025-07-24 22:50 Eric Biggers
2025-07-24 23:16 ` Eric Biggers
0 siblings, 1 reply; 2+ messages in thread
From: Eric Biggers @ 2025-07-24 22:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Ard Biesheuvel, Jason A. Donenfeld, Guenter Roeck
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
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [QEMU bug] [x86_64] Incorrect emulation of vinserti128 instruction
2025-07-24 22:50 [QEMU bug] [x86_64] Incorrect emulation of vinserti128 instruction Eric Biggers
@ 2025-07-24 23:16 ` Eric Biggers
0 siblings, 0 replies; 2+ messages in thread
From: Eric Biggers @ 2025-07-24 23:16 UTC (permalink / raw)
To: qemu-devel
Cc: Ard Biesheuvel, Jason A. Donenfeld, Guenter Roeck, Paolo Bonzini,
Richard Henderson
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 <pbonzini@redhat.com>
Date: Tue Sep 6 10:34:11 2022 +0200
target/i387: reimplement 0x0f 0x3a, add AVX
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-07-24 23:17 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-24 22:50 [QEMU bug] [x86_64] Incorrect emulation of vinserti128 instruction Eric Biggers
2025-07-24 23:16 ` Eric Biggers
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.