@@ -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
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@google.com> --- x86/realmode.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)