}
-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)
{
!= 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++)
default:
break;
}
- return;
+ break;
}
+ return 1;
}
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)
{
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 */
v, list_b, ARRAY_SIZE(list_b), &buffer[index], &match);
}
+ if ( inst_len == 0 )
+ return;
+
inst_len += index;
/* Check for REX prefix - it's ALWAYS the last byte of any prefix bytes */
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 )
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;
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 )