ia64/xen-unstable
changeset 12579:84c0f49de1b1
[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@novell.com>
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@novell.com>
author | kfraser@localhost.localdomain |
---|---|
date | Mon Nov 27 10:06:41 2006 +0000 (2006-11-27) |
parents | b0a86eda868a |
children | f3ee62b7fb52 |
files | xen/arch/x86/hvm/svm/emulate.c xen/arch/x86/hvm/svm/svm.c xen/include/asm-x86/hvm/svm/emulate.h |
line diff
1.1 --- a/xen/arch/x86/hvm/svm/emulate.c Mon Nov 27 10:05:23 2006 +0000 1.2 +++ b/xen/arch/x86/hvm/svm/emulate.c Mon Nov 27 10:06:41 2006 +0000 1.3 @@ -145,8 +145,8 @@ static inline u64 hv_is_canonical(u64 ad 1.4 1.5 1.6 unsigned long get_effective_addr_modrm64(struct vmcb_struct *vmcb, 1.7 - struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, 1.8 - u8 *size) 1.9 + struct cpu_user_regs *regs, const u8 prefix, int inst_len, 1.10 + const u8 *operand, u8 *size) 1.11 { 1.12 unsigned long effective_addr = (unsigned long) -1; 1.13 u8 length, modrm_mod, modrm_rm; 1.14 @@ -191,17 +191,8 @@ unsigned long get_effective_addr_modrm64 1.15 *size = 1; 1.16 break; 1.17 } 1.18 - 1.19 - CHECK_LENGTH64(*size + (u8)sizeof(u32)); 1.20 - 1.21 - memcpy (&disp, operand + 1, sizeof (u32)); 1.22 - *size += sizeof (u32); 1.23 - if (vmcb->cs.attributes.fields.l) // 64-bit mode 1.24 - return vmcb->rip + disp; 1.25 - else 1.26 - return disp; 1.27 - 1.28 #if __x86_64__ 1.29 + /* FALLTHRU */ 1.30 case 0xD: 1.31 if (0 < modrm_mod) 1.32 { 1.33 @@ -209,19 +200,20 @@ unsigned long get_effective_addr_modrm64 1.34 effective_addr = regs->r13; 1.35 break; 1.36 } 1.37 +#endif 1.38 1.39 CHECK_LENGTH64(*size + (u8)sizeof(u32)); 1.40 1.41 memcpy (&disp, operand + 1, sizeof (u32)); 1.42 *size += sizeof (u32); 1.43 1.44 +#if __x86_64__ 1.45 /* 64-bit mode */ 1.46 - if (vmcb->cs.attributes.fields.l) 1.47 - return vmcb->rip + disp; 1.48 - else 1.49 - return disp; 1.50 + if (vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA)) 1.51 + return vmcb->rip + inst_len + *size + disp; 1.52 +#endif 1.53 + return disp; 1.54 1.55 -#endif 1.56 default: 1.57 effective_addr = DECODE_GPR_VALUE(vmcb, regs, modrm_rm); 1.58
2.1 --- a/xen/arch/x86/hvm/svm/svm.c Mon Nov 27 10:05:23 2006 +0000 2.2 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Nov 27 10:06:41 2006 +0000 2.3 @@ -2053,10 +2053,10 @@ void svm_handle_invlpg(const short invlp 2.4 2.5 /* 2.6 * Decode memory operand of the instruction including ModRM, SIB, and 2.7 - * displacement to get effecticve address and length in bytes. Assume 2.8 + * displacement to get effective address and length in bytes. Assume 2.9 * the system in either 32- or 64-bit mode. 2.10 */ 2.11 - g_vaddr = get_effective_addr_modrm64(vmcb, regs, prefix, 2.12 + g_vaddr = get_effective_addr_modrm64(vmcb, regs, prefix, inst_len, 2.13 &opcode[inst_len], &length); 2.14 2.15 inst_len += length;
3.1 --- a/xen/include/asm-x86/hvm/svm/emulate.h Mon Nov 27 10:05:23 2006 +0000 3.2 +++ b/xen/include/asm-x86/hvm/svm/emulate.h Mon Nov 27 10:06:41 2006 +0000 3.3 @@ -77,8 +77,8 @@ enum instruction_index { 3.4 3.5 3.6 extern unsigned long get_effective_addr_modrm64(struct vmcb_struct *vmcb, 3.7 - struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, 3.8 - u8 *size); 3.9 + struct cpu_user_regs *regs, const u8 prefix, int inst_len, 3.10 + const u8 *operand, u8 *size); 3.11 extern unsigned long get_effective_addr_sib(struct vmcb_struct *vmcb, 3.12 struct cpu_user_regs *regs, const u8 prefix, const u8 *operand, 3.13 u8 *size);