[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.2-testing] SVM: handle page faults in emulated instruction fetches
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1205754053 0 # Node ID 0e23995db2eba0052f2ef05f67b845721eef65db # Parent 28e0d4a37bb43079e5db0095a0eed70fc7fa8c13 SVM: handle page faults in emulated instruction fetches Deal with failures in hvm_copy_from_guest_virt when fetching instructions in the various SVM emulation paths. Since we know that the instruction was fetchable by the hardware, we can usually just return from the VMEXIT and try again; whatever caused us to fail will cause the hardware to fail next time and we'll get the correct exit code. Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> xen-unstable changeset: 17202:8325f200e19414d998b7625f2e3cf786a6d3d3a3 xen-unstable date: Mon Mar 17 11:39:50 2008 +0000 --- xen/arch/x86/hvm/svm/emulate.c | 4 +++- xen/arch/x86/hvm/svm/svm.c | 27 +++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) diff -r 28e0d4a37bb4 -r 0e23995db2eb xen/arch/x86/hvm/svm/emulate.c --- a/xen/arch/x86/hvm/svm/emulate.c Wed Mar 05 16:49:33 2008 +0000 +++ b/xen/arch/x86/hvm/svm/emulate.c Mon Mar 17 11:40:53 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 28e0d4a37bb4 -r 0e23995db2eb xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Mar 05 16:49:33 2008 +0000 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Mar 17 11:40:53 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 ) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |