[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v9 0/2] Notify monitor when emulating an unimplemented instruction



This patchset implements a mechanism which allows XEN to send first an event
if the emulator encountered an unsupported instruction.
The monitor application can choose to mitigate the error, for example to 
singlestep
the instruction using the real processor and then resume execution of the normal
instruction flow.

This feature was tested using a modified version of XTF:
https://github.com/petrepircalabu/xen-test-framework/tree/emul_unimpl

---
Changed since v1:
  * Removed the emulation kind check when calling hvm_inject_hw_exception

Changed since v2:
  * Removed a file added by mistake

Changed since v3:
  * Removed extra stray line
  * Added the _enabled suffix to the emul_unhandleable monitor option

Changed since v4
  * Fixed return expression of hvm_monitor_emul_unhandleable handle
  monitor_traps failures.
  * Removed stray parantheses.

Changed since v5:
  * Removed unnecessary "else" when calling hvm_monitor_emul_unhandleable.
  * Added extra line in arch_monitor_domctl_event.

Changed since v6:
  * add the distinction between unimplemented instructions and emulation 
failures.
  * changed "emul_unhandleable" event name to "emul_unimplemented"

Changed since v7:
  * Add "fall-through" comments to the switch statements (coverity)
  * Added X86EMUL_UNIMPLEMENTED to X86EMUL_UNHANDLEABLE checks the in functions
  referencing x86_emulate.
  * Improved comment describing X86EMUL_UNIMPLEMENTED.

Changed since v8:
  * Removed unnecessary "fall-through" comments.
  * Added check for X86EMUL_UNIMPLEMENTED in hvm_ud_intercept.
  * add a new label 'unimplemented_insn' to accomodate the existing jumps to
  'cannot_emulate' (e.g. invoke_stub)

---

Occurences of X86EMUL_UNHANDLEABLE which were not extended to take into account 
X86EMUL_UNIMPLEMENTED:

./xen/arch/x86/x86_emulate/x86_emulate.c:898:    rc = (p) ? 
X86EMUL_UNHANDLEABLE : X86EMUL_OKAY;     \
Used in the fail_if macro. This macro is used to check if certain conditions 
are met while trying to emulate the instruction (e.g. fail_if(!ops->read_msr); 
).
This macro should not be modified as these conditions are not related to the 
instruction decoding and classification.

./xen/arch/x86/x86_emulate/x86_emulate.c:3429:        rc = X86EMUL_UNHANDLEABLE;
./xen/arch/x86/x86_emulate/x86_emulate.c:3433:            if ( rc != 
X86EMUL_UNHANDLEABLE )
./xen/arch/x86/x86_emulate/x86_emulate.c:3436:        if ( (nr_reps > 1 || rc 
== X86EMUL_UNHANDLEABLE) && ops->rep_ins )
./xen/arch/x86/x86_emulate/x86_emulate.c:3439:        if ( nr_reps >= 1 && rc 
== X86EMUL_UNHANDLEABLE )
./xen/arch/x86/x86_emulate/x86_emulate.c:3469:        rc = X86EMUL_UNHANDLEABLE;
x86_emulate: while emulating ins %dx,%es:%edi the return code is initialized to 
X86EMUL_UNHANDLEABLE and is used to hold / check the result of various 
emulation ops (x86_emulate_ops) (read_id, rep_ins).
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/x86_emulate/x86_emulate.c:3474:            if ( rc != 
X86EMUL_UNHANDLEABLE )
./xen/arch/x86/x86_emulate/x86_emulate.c:3477:        if ( (nr_reps > 1 || rc 
== X86EMUL_UNHANDLEABLE) && ops->rep_outs )
./xen/arch/x86/x86_emulate/x86_emulate.c:3480:        if ( nr_reps >= 1 && rc 
== X86EMUL_UNHANDLEABLE )
./xen/arch/x86/x86_emulate/x86_emulate.c:3756:                                  
&nr_reps, ctxt)) == X86EMUL_UNHANDLEABLE) )
x86_emulate: while emulatings outs %esi,%dx the return code is initialized to 
X86EMUL_UNHANDLEABLE and is used to hold / check the result of various 
emulation ops (x86_emulate_ops) (rep_outs, write_io) and read_ulong.
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/x86_emulate/x86_emulate.c:3802:                                  
&nr_reps, ctxt)) == X86EMUL_UNHANDLEABLE) )
x86_emulate: while emulating stos, if rep_stos returns X86EMUL_UNHANDLEABLE, 
the return value is reset to X86EMUL_OKAY. The emulation callbacks should not 
return X86EMUL_UNIMPLEMENTED as they are not used by the decoding logic of an 
instruction.
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/x86_emulate/x86_emulate.c:5082:                else if ( rc != 
X86EMUL_UNHANDLEABLE )
x86_emulate: while emulating clzero the return value of rep_stos is check 
against X86EMUL_UNHANDLEABLE. The emulation callbacks should not return 
X86EMUL_UNIMPLEMENTED as they are not used by the decoding logic of an 
instruction.
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/hvm/emulate.c:170:            return X86EMUL_UNHANDLEABLE;
./xen/arch/x86/hvm/emulate.c:175:        return X86EMUL_UNHANDLEABLE;
hvmemul_do_io: returns X86EMUL_UNHANDLEABLE if the io_req state is invalid.
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/hvm/emulate.c:202:    case X86EMUL_UNHANDLEABLE:
hvmemul_do_io:  The function checks against X86EMUL_UNHANDLEABLE the return of 
hvm_io_intercept (which in turn calls hvm_process_io_intercept).
hvm_process_io_intercept does not (and should not ever) return 
X86EMUL_UNIMPLEMENTED as it's just performs copies to/from the guest phys 
memory.
Should not be changed to X86EMUL_UNIMPLEMENTED as it's not applicable.

./xen/arch/x86/hvm/emulate.c:318:    if ( rc == X86EMUL_UNHANDLEABLE && dir == 
IOREQ_READ )
hvmemul_do_io_buffer: Checks against X86EMUL_UNHANDLEABLE the return value of 
hvmemul_do_io (which cannot return X86EMUL_UNIMPLEMENTED).
Should not be changed to X86EMUL_UNIMPLEMENTED as it's not applicable.

./xen/arch/x86/hvm/emulate.c:1152:           ? X86EMUL_OKAY : 
X86EMUL_UNHANDLEABLE;
hvmemul_validate: returns X86EMUL_UNHANDLEABLE if the context provided validate 
function returns false. 
Should not be changed to X86EMUL_UNIMPLEMENTED as the validate function only 
limits the instructions supported by the emulator to
a specific context. 

./xen/arch/x86/hvm/intercept.c:151:                    return 
X86EMUL_UNHANDLEABLE;
./xen/arch/x86/hvm/intercept.c:179:                    return 
X86EMUL_UNHANDLEABLE;
./xen/arch/x86/hvm/intercept.c:199:    else if ( rc == X86EMUL_UNHANDLEABLE )
hvm_process_io_intercept: returns X86EMUL_UNHANDLEABLE if the read/write 
(including hvm_copy_[from/to]_guest_phys) functions failed.
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

./xen/arch/x86/hvm/intercept.c:245:        return X86EMUL_UNHANDLEABLE;
hvm_io_intercept: returns X86EMUL_UNHANDLEABLE if hvm_io_handler is unavailable 
or hvm_process_io_intercept returns an error;
Should not be changed to X86EMUL_UNIMPLEMENTED as it’s not related to 
instruction decoding.

---
  x86emul: New return code for unimplemented instruction
  x86/monitor: Notify monitor if an emulation fails.

 tools/libxc/include/xenctrl.h          |  2 ++
 tools/libxc/xc_monitor.c               | 14 ++++++++++++++
 xen/arch/x86/hvm/emulate.c             |  7 +++++++
 xen/arch/x86/hvm/hvm.c                 |  1 +
 xen/arch/x86/hvm/io.c                  |  1 +
 xen/arch/x86/hvm/monitor.c             | 17 +++++++++++++++++
 xen/arch/x86/hvm/vmx/realmode.c        |  2 +-
 xen/arch/x86/mm/shadow/multi.c         |  2 +-
 xen/arch/x86/monitor.c                 | 13 +++++++++++++
 xen/arch/x86/x86_emulate/x86_emulate.c | 35 ++++++++++++++++++----------------
 xen/arch/x86/x86_emulate/x86_emulate.h |  6 ++++++
 xen/include/asm-x86/domain.h           |  1 +
 xen/include/asm-x86/hvm/monitor.h      |  1 +
 xen/include/asm-x86/monitor.h          |  3 ++-
 xen/include/public/domctl.h            |  1 +
 xen/include/public/vm_event.h          |  2 ++
 16 files changed, 89 insertions(+), 19 deletions(-)

-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.