ia64/xen-unstable
changeset 17219:8325f200e194
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@citrix.com>
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@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Mar 17 11:39:50 2008 +0000 (2008-03-17) |
parents | f82baf1755ac |
children | 9b0ee101c2e2 |
files | xen/arch/x86/hvm/svm/emulate.c xen/arch/x86/hvm/svm/svm.c |
line diff
1.1 --- a/xen/arch/x86/hvm/svm/emulate.c Mon Mar 17 11:18:06 2008 +0000 1.2 +++ b/xen/arch/x86/hvm/svm/emulate.c Mon Mar 17 11:39:50 2008 +0000 1.3 @@ -117,7 +117,9 @@ int __get_instruction_length_from_list(s 1.4 } 1.5 else 1.6 { 1.7 - inst_copy_from_guest(buffer, svm_rip2pointer(v), MAX_INST_LEN); 1.8 + if ( inst_copy_from_guest(buffer, svm_rip2pointer(v), MAX_INST_LEN) 1.9 + != MAX_INST_LEN ) 1.10 + return 0; 1.11 buf = buffer; 1.12 } 1.13
2.1 --- a/xen/arch/x86/hvm/svm/svm.c Mon Mar 17 11:18:06 2008 +0000 2.2 +++ b/xen/arch/x86/hvm/svm/svm.c Mon Mar 17 11:39:50 2008 +0000 2.3 @@ -943,6 +943,10 @@ static void svm_vmexit_do_cpuid(struct c 2.4 { 2.5 unsigned int eax, ebx, ecx, edx, inst_len; 2.6 2.7 + inst_len = __get_instruction_length(current, INSTR_CPUID, NULL); 2.8 + if ( inst_len == 0 ) 2.9 + return; 2.10 + 2.11 eax = regs->eax; 2.12 ebx = regs->ebx; 2.13 ecx = regs->ecx; 2.14 @@ -955,7 +959,6 @@ static void svm_vmexit_do_cpuid(struct c 2.15 regs->ecx = ecx; 2.16 regs->edx = edx; 2.17 2.18 - inst_len = __get_instruction_length(current, INSTR_CPUID, NULL); 2.19 __update_guest_eip(regs, inst_len); 2.20 } 2.21 2.22 @@ -1166,6 +1169,8 @@ static void svm_vmexit_do_hlt(struct vmc 2.23 unsigned int inst_len; 2.24 2.25 inst_len = __get_instruction_length(curr, INSTR_HLT, NULL); 2.26 + if ( inst_len == 0 ) 2.27 + return 0; 2.28 __update_guest_eip(regs, inst_len); 2.29 2.30 /* Check for pending exception or new interrupt. */ 2.31 @@ -1354,6 +1359,8 @@ asmlinkage void svm_vmexit_handler(struc 2.32 2.33 case VMEXIT_VMMCALL: 2.34 inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL); 2.35 + if ( inst_len == 0 ) 2.36 + break; 2.37 HVMTRACE_1D(VMMCALL, v, regs->eax); 2.38 rc = hvm_do_hypercall(regs); 2.39 if ( rc != HVM_HCALL_preempted )