target-sparc: fix ldstub sign-extension bug

ldstub [addr], reg incorrectly reads a signed byte from memory which causes
problems in the 32-bit Solaris mutex code. Here the byte value being read is
0xff which is incorrectly sign-extended to 0xffffffff before being written back
to the target register causing lock detection to behave incorrectly.

This fixes the intermittent hangs and MUTEX_HELD warnings issued to the
console when running 32-bit Solaris images under qemu-system-sparc.

With thanks to Joseph Dery for providing a condensed test image to consistently
reproduce the problem on demand, and Martin Husemann for allowing me access to
real hardware for comparison.

Backports commit 4553e10360a0713e31647220ed396942f9a6fca0 from qemu
This commit is contained in:
Mark Cave-Ayland 2018-02-23 13:37:14 -05:00 committed by Lioncash
parent 4cacbf212f
commit 7dcdae9807
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -4807,7 +4807,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
TCGv r_const;
gen_address_mask(dc, cpu_addr);
tcg_gen_qemu_ld8s(dc->uc, cpu_val, cpu_addr, dc->mem_idx);
tcg_gen_qemu_ld8u(dc->uc, cpu_val, cpu_addr, dc->mem_idx);
r_const = tcg_const_tl(tcg_ctx, 0xff);
tcg_gen_qemu_st8(dc->uc, r_const, cpu_addr, dc->mem_idx);
tcg_temp_free(tcg_ctx, r_const);