aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-04-19 20:51:47 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2024-04-23 17:35:26 +0200
commit7653b44534d3267fa63ebc9d7221eaa7b48bf5ae (patch)
tree4c75bbba62547f5ec14e84534c8172fef71f861b
parent9c05071719ca3a479b677e58db8ab0c5ad3f9b83 (diff)
downloadqemu-7653b44534d3267fa63ebc9d7221eaa7b48bf5ae.zip
qemu-7653b44534d3267fa63ebc9d7221eaa7b48bf5ae.tar.gz
qemu-7653b44534d3267fa63ebc9d7221eaa7b48bf5ae.tar.bz2
target/i386/translate.c: always write 32-bits for SGDT and SIDT
The various Intel CPU manuals claim that SGDT and SIDT can write either 24-bits or 32-bits depending upon the operand size, but this is incorrect. Not only do the Intel CPU manuals give contradictory information between processor revisions, but this information doesn't even match real-life behaviour. In fact, tests on real hardware show that the CPU always writes 32-bits for SGDT and SIDT, and this behaviour is required for at least OS/2 Warp and WFW 3.11 with Win32s to function correctly. Remove the masking applied due to the operand size for SGDT and SIDT so that the TCG behaviour matches the behaviour on real hardware. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2198 -- MCA: Whilst I don't have a copy of OS/2 Warp handy, I've confirmed that this patch fixes the issue in WFW 3.11 with Win32s. For more technical information I highly recommend the excellent write-up at https://www.os2museum.com/wp/sgdtsidt-fiction-and-reality/. Message-ID: <20240419195147.434894-1-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--target/i386/tcg/translate.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 76a42c6..c05d9e5 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -5846,9 +5846,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_op_st_v(s, MO_16, s->T0, s->A0);
gen_add_A0_im(s, 2);
tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, gdt.base));
- if (dflag == MO_16) {
- tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
- }
+ /*
+ * NB: Despite a confusing description in Intel CPU documentation,
+ * all 32-bits are written regardless of operand size.
+ */
gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
break;
@@ -5901,9 +5902,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_op_st_v(s, MO_16, s->T0, s->A0);
gen_add_A0_im(s, 2);
tcg_gen_ld_tl(s->T0, tcg_env, offsetof(CPUX86State, idt.base));
- if (dflag == MO_16) {
- tcg_gen_andi_tl(s->T0, s->T0, 0xffffff);
- }
+ /*
+ * NB: Despite a confusing description in Intel CPU documentation,
+ * all 32-bits are written regardless of operand size.
+ */
gen_op_st_v(s, CODE64(s) + MO_32, s->T0, s->A0);
break;