[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [PATCH] svm: fix RIP-relative addressing in invlpg emulation
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 84c0f49de1b1e241a4b409a48192c110b01788a0 # Parent b0a86eda868a047e444da80291ab8755f2d62238 [PATCH] svm: fix RIP-relative addressing in invlpg emulation RIP-relative addressing as relative to the beginning of the next (or, in other word, the end of the current) instruction. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- xen/arch/x86/hvm/svm/emulate.c | 26 +++++++++----------------- xen/arch/x86/hvm/svm/svm.c | 4 ++-- xen/include/asm-x86/hvm/svm/emulate.h | 4 ++-- 3 files changed, 13 insertions(+), 21 deletions(-) diff -r b0a86eda868a -r 84c0f49de1b1 xen/arch/x86/hvm/svm/emulate.c --- a/xen/arch/x86/hvm/svm/emulate.c Mon Nov 27 10:05:23 2006 +0000 +++ b/xen/arch/x86/hvm/svm/emulate.c Mon Nov 27 10:06:41 2006 +0000 @@ -145,8 +145,8 @@ static inline u64 hv_is_canonical(u64 ad unsigned long get_effective_addr_modrm64(struct vmcb_struct *vmcb, - struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, - u8 *size) + struct cpu_user_regs *regs, const u8 prefix, int inst_len, + const u8 *operand, u8 *size) { unsigned long effective_addr = (unsigned long) -1; u8 length, modrm_mod, modrm_rm; @@ -191,17 +191,8 @@ unsigned long get_effective_addr_modrm64 *size = 1; break; } - - CHECK_LENGTH64(*size + (u8)sizeof(u32)); - - memcpy (&disp, operand + 1, sizeof (u32)); - *size += sizeof (u32); - if (vmcb->cs.attributes.fields.l) // 64-bit mode - return vmcb->rip + disp; - else - return disp; - #if __x86_64__ + /* FALLTHRU */ case 0xD: if (0 < modrm_mod) { @@ -209,19 +200,20 @@ unsigned long get_effective_addr_modrm64 effective_addr = regs->r13; break; } +#endif CHECK_LENGTH64(*size + (u8)sizeof(u32)); memcpy (&disp, operand + 1, sizeof (u32)); *size += sizeof (u32); +#if __x86_64__ /* 64-bit mode */ - if (vmcb->cs.attributes.fields.l) - return vmcb->rip + disp; - else - return disp; - + if (vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA)) + return vmcb->rip + inst_len + *size + disp; #endif + return disp; + default: effective_addr = DECODE_GPR_VALUE(vmcb, regs, modrm_rm); diff -r b0a86eda868a -r 84c0f49de1b1 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Nov 27 10:05:23 2006 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Nov 27 10:06:41 2006 +0000 @@ -2053,10 +2053,10 @@ void svm_handle_invlpg(const short invlp /* * Decode memory operand of the instruction including ModRM, SIB, and - * displacement to get effecticve address and length in bytes. Assume + * displacement to get effective address and length in bytes. Assume * the system in either 32- or 64-bit mode. */ - g_vaddr = get_effective_addr_modrm64(vmcb, regs, prefix, + g_vaddr = get_effective_addr_modrm64(vmcb, regs, prefix, inst_len, &opcode[inst_len], &length); inst_len += length; diff -r b0a86eda868a -r 84c0f49de1b1 xen/include/asm-x86/hvm/svm/emulate.h --- a/xen/include/asm-x86/hvm/svm/emulate.h Mon Nov 27 10:05:23 2006 +0000 +++ b/xen/include/asm-x86/hvm/svm/emulate.h Mon Nov 27 10:06:41 2006 +0000 @@ -77,8 +77,8 @@ enum instruction_index { extern unsigned long get_effective_addr_modrm64(struct vmcb_struct *vmcb, - struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, - u8 *size); + struct cpu_user_regs *regs, const u8 prefix, int inst_len, + const u8 *operand, u8 *size); extern unsigned long get_effective_addr_sib(struct vmcb_struct *vmcb, struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, u8 *size); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |