Those are: X86_OP_MOV_IMMEDIATE_TO_MEM 0xc7 X86_OP_MOV_MEM_TO_RAX 0xa1 X86_OP_MOV_RAX_TO_MEM 0xa3
The reason to bring them in is that the code is simple enough and will enable one more guest OS (Zephyr OS) to function in xAPIC mode as well. Signed-off-by: Gustavo Lima Chaves <[email protected]> --- hypervisor/arch/x86/apic.c | 6 ++++- hypervisor/arch/x86/include/asm/mmio.h | 3 +++ hypervisor/arch/x86/include/asm/processor.h | 3 +++ hypervisor/arch/x86/mmio.c | 35 ++++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/hypervisor/arch/x86/apic.c b/hypervisor/arch/x86/apic.c index f09d093..73e240b 100644 --- a/hypervisor/arch/x86/apic.c +++ b/hypervisor/arch/x86/apic.c @@ -504,7 +504,11 @@ unsigned int apic_mmio_access(unsigned long rip, return 0; } if (is_write) { - val = this_cpu_data()->guest_regs.by_index[inst.reg_num]; + if (inst.has_immediate) + val = inst.immediate; + else + val = this_cpu_data()->guest_regs.by_index[inst.reg_num]; + if (apic_accessing_reserved_bits(reg, val)) return 0; diff --git a/hypervisor/arch/x86/include/asm/mmio.h b/hypervisor/arch/x86/include/asm/mmio.h index 72aecab..5c26c5c 100644 --- a/hypervisor/arch/x86/include/asm/mmio.h +++ b/hypervisor/arch/x86/include/asm/mmio.h @@ -28,6 +28,9 @@ struct mmio_instruction { /** Number of the register that holds the output value or should * receive the input. */ unsigned int reg_num; + /** Immediate value, when due */ + signed int immediate; + bool has_immediate; }; /** diff --git a/hypervisor/arch/x86/include/asm/processor.h b/hypervisor/arch/x86/include/asm/processor.h index a658039..e3c36ed 100644 --- a/hypervisor/arch/x86/include/asm/processor.h +++ b/hypervisor/arch/x86/include/asm/processor.h @@ -148,6 +148,9 @@ #define X86_OP_MOVB_TO_MEM 0x88 #define X86_OP_MOV_TO_MEM 0x89 #define X86_OP_MOV_FROM_MEM 0x8b +#define X86_OP_MOV_IMMEDIATE_TO_MEM 0xc7 +#define X86_OP_MOV_MEM_TO_RAX 0xa1 +#define X86_OP_MOV_RAX_TO_MEM 0xa3 #define DB_VECTOR 1 #define NMI_VECTOR 2 diff --git a/hypervisor/arch/x86/mmio.c b/hypervisor/arch/x86/mmio.c index 7ca2ba8..7d3a3ab 100644 --- a/hypervisor/arch/x86/mmio.c +++ b/hypervisor/arch/x86/mmio.c @@ -78,7 +78,8 @@ struct mmio_instruction x86_mmio_parse(unsigned long pc, const struct guest_paging_structures *pg_structs, bool is_write) { struct parse_context ctx = { .remaining = X86_MAX_INST_LEN }; - struct mmio_instruction inst = { .inst_len = 0 }; + struct mmio_instruction inst = { .inst_len = 0, .has_immediate = false }; + const u8 *inst_start = NULL; union opcode op[4] = { }; bool does_write = false; bool has_rex_w = false; @@ -88,6 +89,9 @@ restart: if (!ctx_maybe_get_bytes(&ctx, &pc, pg_structs)) goto error_noinst; + if (!inst_start) + inst_start = ctx.inst; + op[0].raw = *(ctx.inst); if (op[0].rex.code == X86_REX_CODE) { if (op[0].rex.w) @@ -126,6 +130,23 @@ restart: inst.inst_len += 2; inst.access_size = 4; break; + case X86_OP_MOV_IMMEDIATE_TO_MEM: + inst.inst_len += 2; + inst.access_size = 4; + inst.has_immediate = true; + does_write = true; + break; + case X86_OP_MOV_MEM_TO_RAX: + inst.inst_len += 5; + inst.access_size = 4; + inst.reg_num = 15; + goto final; + case X86_OP_MOV_RAX_TO_MEM: + inst.inst_len += 5; + inst.access_size = 4; + inst.reg_num = 15; + does_write = true; + goto final; default: goto error_unsupported; } @@ -138,6 +159,8 @@ restart: case 0: if (op[2].modrm.rm == 5) { /* 32-bit displacement */ inst.inst_len += 4; + if (inst.has_immediate) + inst.inst_len += 4; break; } else if (op[2].modrm.rm != 4) { /* no SIB */ break; @@ -168,6 +191,16 @@ restart: else inst.reg_num = 15 - op[2].modrm.reg; +final: + /* FIXME: what if an instruction with immediate spans two + * pages? */ + if (inst.has_immediate) { + if (ctx.inst - inst_start + ctx.size < inst.inst_len) + goto error_noinst; + inst.immediate = *(typeof(inst.immediate)*) + (inst_start + inst.inst_len - sizeof(inst.immediate)); + } + if (does_write != is_write) goto error_inconsitent; -- 2.13.5 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
