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
> 

Reply via email to