Clang prefers to use a "rep;movsl" (or equivalent) to copy the "regs" structure. This doesn't work in 16-bit mode, as it will end up copying over half the number of bytes. Avoid this by copying over the structure a byte at a time. Signed-off-by: Bill Wendling <morbo@xxxxxxxxxx> --- x86/realmode.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/x86/realmode.c b/x86/realmode.c index 303d093..41b8592 100644 --- a/x86/realmode.c +++ b/x86/realmode.c @@ -140,6 +140,16 @@ struct insn_desc { static struct regs inregs, outregs; +static inline void copy_regs(struct regs *dst_regs, struct regs *src_regs) +{ + char *dst = (char*)dst_regs; + char *src = (char*)src_regs; + u32 i; + + for (i = 0; i < sizeof(struct regs); i++) + dst[i] = src[i]; +} + static void exec_in_big_real_mode(struct insn_desc *insn) { unsigned long tmp; @@ -148,11 +158,11 @@ static void exec_in_big_real_mode(struct insn_desc *insn) extern u8 test_insn[], test_insn_end[]; for (i = 0; i < insn->len; ++i) - test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i]; + test_insn[i] = ((u8 *)(unsigned long)insn->ptr)[i]; for (; i < test_insn_end - test_insn; ++i) test_insn[i] = 0x90; // nop - save = inregs; + copy_regs(&save, &inregs); asm volatile( "lgdtl %[gdt_descr] \n\t" "mov %%cr0, %[tmp] \n\t" @@ -196,7 +206,8 @@ static void exec_in_big_real_mode(struct insn_desc *insn) : [gdt_descr]"m"(gdt_descr), [bigseg]"r"((short)16) : "cc", "memory" ); - outregs = save; + copy_regs(&outregs, &save); + } #define R_AX 1 -- 2.23.0.700.g56cf767bdb-goog