diff -r a1938d7eebb6 xen/arch/x86/hvm/svm/emulate.c --- a/xen/arch/x86/hvm/svm/emulate.c Mon Mar 10 13:01:40 2008 +0000 +++ b/xen/arch/x86/hvm/svm/emulate.c Mon Mar 10 13:01:40 2008 +0000 @@ -435,7 +435,9 @@ int __get_instruction_length_from_list(s } else { - inst_copy_from_guest(buffer, svm_rip2pointer(v), MAX_INST_LEN); + if ( inst_copy_from_guest(buffer, svm_rip2pointer(v), MAX_INST_LEN) + != MAX_INST_LEN ) + return 0; buf = buffer; } diff -r a1938d7eebb6 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Mon Mar 10 13:01:40 2008 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Mar 10 13:02:32 2008 +0000 @@ -1128,7 +1128,7 @@ static void svm_dr_access(struct vcpu *v } -static void svm_get_prefix_info(struct vcpu *v, unsigned int dir, +static int svm_get_prefix_info(struct vcpu *v, unsigned int dir, svm_segment_register_t **seg, unsigned int *asize) { @@ -1141,8 +1141,7 @@ static void svm_get_prefix_info(struct v != MAX_INST_LEN) { gdprintk(XENLOG_ERR, "get guest instruction failed\n"); - domain_crash(current->domain); - return; + return 0; } for (i = 0; i < MAX_INST_LEN; i++) @@ -1200,8 +1199,9 @@ static void svm_get_prefix_info(struct v default: break; } - return; - } + break; + } + return 1; } @@ -1236,7 +1236,8 @@ static int svm_get_io_address( isize --; if (isize > 1) - svm_get_prefix_info(v, info.fields.type, &seg, &asize); + if ( !svm_get_prefix_info(v, info.fields.type, &seg, &asize) ) + return 0; if (info.fields.type == IOREQ_WRITE) { @@ -1591,7 +1592,10 @@ static void svm_cr_access( enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW}; enum instruction_index match; - inst_copy_from_guest(buffer, svm_rip2pointer(v), sizeof(buffer)); + if ( inst_copy_from_guest(buffer, svm_rip2pointer(v), sizeof(buffer)) + != sizeof buffer ) + /* #PF will have been delivered if appropriate. */ + return; /* get index to first actual instruction byte - as we will need to know where the prefix lives later on */ @@ -1607,6 +1611,9 @@ static void svm_cr_access( inst_len = __get_instruction_length_from_list( v, list_b, ARRAY_SIZE(list_b), &buffer[index], &match); } + + if ( inst_len == 0 ) + return; inst_len += index; @@ -1940,7 +1947,7 @@ void svm_handle_invlpg(const short invlp if ( inst_copy_from_guest(opcode, svm_rip2pointer(v), length) < length ) { gdprintk(XENLOG_ERR, "Error reading memory %d bytes\n", length); - goto crash; + return; } if ( invlpga ) @@ -2055,6 +2062,8 @@ asmlinkage void svm_vmexit_handler(struc goto exit_and_crash; /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */ inst_len = __get_instruction_length(v, INSTR_INT3, NULL); + if ( inst_len == 0 ) + break; __update_guest_eip(regs, inst_len); domain_pause_for_debugger(); break; @@ -2131,6 +2140,8 @@ asmlinkage void svm_vmexit_handler(struc case VMEXIT_VMMCALL: inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL); + if ( inst_len == 0 ) + break; HVMTRACE_1D(VMMCALL, v, regs->eax); rc = hvm_do_hypercall(regs); if ( rc != HVM_HCALL_preempted )