File 5832fe49-svm_nextrip_insn_length-when-crossing-boundary-to-0.patch of Package xen.4216
# Commit 0745f665a575bdb6724f6ec1ab767cd71ba8c253
# Date 2016-11-21 14:01:45 +0000
# Author Andrew Cooper <andrew.cooper3@citrix.com>
# Committer Andrew Cooper <andrew.cooper3@citrix.com>
x86/svm: Fix svm_nextrip_insn_length() when crossing the virtual boundary to 0
vmcb->nextrip can legitimately be less than vmcb->rip when execution wraps
back around to 0. Instead, complain if the reported length is greater than 15
and use x86_decode_insn() as a fallback.
While making changes here, fix two whitespace issues with the case labels.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
# Commit f678e2c78110e73431217306bbd33c736802d700
# Date 2016-11-21 17:17:51 +0000
# Author Andrew Cooper <andrew.cooper3@citrix.com>
# Committer Andrew Cooper <andrew.cooper3@citrix.com>
x86/hvm: Fix non-debug build folling c/s 0745f665a5
The variable is named inst_len, not insn_len.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
--- a/xen/arch/x86/hvm/svm/emulate.c
+++ b/xen/arch/x86/hvm/svm/emulate.c
@@ -65,18 +65,18 @@ static unsigned long svm_nextrip_insn_le
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- if ( !cpu_has_svm_nrips || (vmcb->nextrip <= vmcb->rip) )
+ if ( !cpu_has_svm_nrips )
return 0;
#ifndef NDEBUG
switch ( vmcb->exitcode )
{
- case VMEXIT_CR0_READ... VMEXIT_DR15_WRITE:
+ case VMEXIT_CR0_READ ... VMEXIT_DR15_WRITE:
/* faults due to instruction intercepts */
/* (exitcodes 84-95) are reserved */
case VMEXIT_IDTR_READ ... VMEXIT_TR_WRITE:
case VMEXIT_RDTSC ... VMEXIT_MSR:
- case VMEXIT_VMRUN ... VMEXIT_XSETBV:
+ case VMEXIT_VMRUN ... VMEXIT_XSETBV:
/* ...and the rest of the #VMEXITs */
case VMEXIT_CR0_SEL_WRITE:
case VMEXIT_EXCEPTION_BP:
@@ -156,14 +156,16 @@ int __get_instruction_length_from_list(s
const enum instruction_index *list, unsigned int list_count)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- unsigned int i, j, inst_len = 0;
+ unsigned int i, j;
enum instruction_index instr = 0;
u8 buf[MAX_INST_LEN];
const u8 *opcode = NULL;
- unsigned long fetch_addr, fetch_limit;
+ unsigned long fetch_addr, fetch_limit, inst_len;
unsigned int fetch_len, max_len;
- if ( (inst_len = svm_nextrip_insn_length(v)) != 0 )
+ if ( (inst_len = svm_nextrip_insn_length(v)) > MAX_INST_LEN )
+ gprintk(XENLOG_WARNING, "NRip reported inst_len %lu\n", inst_len);
+ else if ( inst_len != 0 )
return inst_len;
if ( vmcb->exitcode == VMEXIT_IOIO )
@@ -180,7 +182,7 @@ int __get_instruction_length_from_list(s
if ( !fetch(vmcb, buf, fetch_addr, fetch_len) )
return 0;
- while ( (inst_len < max_len) && is_prefix(buf[inst_len]) )
+ for ( inst_len = 0; (inst_len < max_len) && is_prefix(buf[inst_len]); )
{
inst_len++;
if ( inst_len >= fetch_len )