v2 is out, now a two-patch series with the regression test split out: https://lore.kernel.org/qemu-devel/[email protected]/
Paul On Thu, 10 Sep 2026, at 13:13, Paul Galbraith wrote: > Ping on this one. > > Short version: in a 16-bit code segment, a near CALL or JMP rel16 that only > reaches its target by wrapping EIP through 0xFFFF runs with EIP left > untruncated. The SDM has the 16-bit form truncate EIP to 16 bits, so in my > test the branch should land at CS:0x0020, and instead execution carries on at > EIP 0x10020. > > It's fiddly to hit. You need all four of these at once: > > - a 16-bit code segment, D/B clear, so it really is a rel16 and EIP really > is masked to 16 bits > > - a cs_base that isn't page aligned. If it is aligned, the wrap always > crosses a page boundary in the linear address too, and the existing > same-page test happens to give the right answer > > - the untruncated linear target landing in the same guest page as the start > of the TB, which is what makes gen_jmp_rel() skip the masking > > - a CF_PCREL translation. It goes away under -d nochain and under > -accel tcg,one-insn-per-tb=on, both of which set CF_NO_GOTO_TB and force > the masking back on > > One thing I got wrong in v1: it dropped the data16-in-code32 guard on the > assumption that the new condition subsumed it. It doesn't. That guard is > there for a different case, EIP starting out above the mask, so v1 would have > swapped one problem for another. v2 does something narrower and leaves the > guard where it is. > > The test is the same test with the same geometry, just split out into its own > patch and wired into tests/tcg/i386/system/meson.build now that the tcg tests > meson rework has landed. > > I'll send v2 as a new thread shortly and link it back here. > > Paul >
