Hi, Gentle ping on this patch from August 26. Could you please take a look when you have time?
Patch archive <https://www.mail-archive.com/[email protected]/msg1220122.html> I'm happy to address any feedback. Thanks ср, 26 авг. 2026 г. в 20:16, Artemii Mashanov <[email protected]>: > TCG's do_xsave_fpu() omitted writing the FOP field and the reserved > bytes (10..15) of each x87 register slot. Those parts of > the destination buffer retained their previous contents. > > The reserved bytes of all eight slots are zeroed. TCG does not > yet track the actual FOP value, this patch stores a fixed zero instead. > > Add a regression test in tests/tcg/x86_64/fxsave.c. It fills the > FXSAVE area with 0xcc, executes FNINIT and FXSAVE64, then verifies that > FOP and all reserved slot bytes are zero. > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3522 > > Signed-off-by: Artemii Mashanov <[email protected]> > --- > target/i386/tcg/fpu_helper.c | 3 ++ > tests/tcg/x86_64/Makefile.target | 1 + > tests/tcg/x86_64/fxsave.c | 66 ++++++++++++++++++++++++++++++++ > 3 files changed, 70 insertions(+) > create mode 100644 tests/tcg/x86_64/fxsave.c > > diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c > index b812125efa..9a2be488ef 100644 > --- a/target/i386/tcg/fpu_helper.c > +++ b/target/i386/tcg/fpu_helper.c > @@ -2601,6 +2601,7 @@ static void do_xsave_fpu(X86Access *ac, target_ulong > ptr) > access_stw(ac, ptr + XO(legacy.fcw), env->fpuc); > access_stw(ac, ptr + XO(legacy.fsw), fpus); > access_stw(ac, ptr + XO(legacy.ftw), fptag ^ 0xff); > + access_stw(ac, ptr + XO(legacy.fpop), 0); > > /* In 32-bit mode this is eip, sel, dp, sel. > In 64-bit mode this is rip, rdp. > @@ -2613,6 +2614,8 @@ static void do_xsave_fpu(X86Access *ac, target_ulong > ptr) > for (i = 0; i < 8; i++) { > floatx80 tmp = ST(i); > do_fstt(ac, addr, tmp); > + access_stw(ac, addr + 10, 0); > + access_stl(ac, addr + 12, 0); > addr += 16; > } > } > diff --git a/tests/tcg/x86_64/Makefile.target > b/tests/tcg/x86_64/Makefile.target > index c48767fef8..0f8f48b1a5 100644 > --- a/tests/tcg/x86_64/Makefile.target > +++ b/tests/tcg/x86_64/Makefile.target > @@ -20,6 +20,7 @@ X86_64_TESTS += test-1648 > X86_64_TESTS += test-2175 > X86_64_TESTS += cross-modifying-code > X86_64_TESTS += fma > +X86_64_TESTS += fxsave > TESTS=$(MULTIARCH_TESTS) $(X86_64_TESTS) test-x86_64 > else > TESTS=$(MULTIARCH_TESTS) > diff --git a/tests/tcg/x86_64/fxsave.c b/tests/tcg/x86_64/fxsave.c > new file mode 100644 > index 0000000000..d08a4e8a0e > --- /dev/null > +++ b/tests/tcg/x86_64/fxsave.c > @@ -0,0 +1,66 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + * See https://gitlab.com/qemu-project/qemu/-/issues/3522 > + */ > + > +#include <stdint.h> > +#include <stdio.h> > +#include <string.h> > + > +#define FXSAVE_FOP_OFFSET 6 > +#define FXSAVE_X87_OFFSET 32 > +#define FXSAVE_SLOT_SIZE 16 > +#define FXSAVE_RESERVED_START 10 > +#define FXSAVE_NUM_SLOTS 8 > + > +struct fxsave_area { > + uint8_t raw[512]; > +} __attribute__((aligned(16))); > + > +_Static_assert(sizeof(struct fxsave_area) == 512, > + "FXSAVE area must be exactly 512 bytes"); > + > +static uint16_t u16_le(const uint8_t *p) > +{ > + uint16_t v; > + memcpy(&v, p, sizeof(v)); > + return v; > +} > + > +int main(void) > +{ > + struct fxsave_area area; > + uint16_t fop; > + > + memset(&area, 0xcc, sizeof(area)); > + > + __asm__ volatile( > + "fninit\n\t" > + "fxsave64 %0" > + : "+m" (area) > + : > + : "memory" > + ); > + > + fop = u16_le(&area.raw[FXSAVE_FOP_OFFSET]); > + if (fop != 0) { > + fprintf(stderr, "FOP: expected 0, got 0x%04x\n", (unsigned)fop); > + return 1; > + } > + > + for (int slot = 0; slot < FXSAVE_NUM_SLOTS; slot++) { > + int base = FXSAVE_X87_OFFSET + slot * FXSAVE_SLOT_SIZE; > + for (int b = FXSAVE_RESERVED_START; b < FXSAVE_SLOT_SIZE; b++) { > + uint8_t val = area.raw[base + b]; > + if (val != 0) { > + fprintf(stderr, > + "Slot %d byte %d (offset %d): expected 0x00, " > + "got 0x%02x\n", > + slot, b, base + b, (unsigned)val); > + return 1; > + } > + } > + } > + > + return 0; > +} > -- > 2.54.0 > >
