mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86 hvm: Simplify and consolidate logic for HLT emulation.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
This commit is contained in:
1 parent
8be7a2fd46
commit
7fd7bda80c
3 files changed
+11
-31
No files matched your search
@@ -46,6 +46,7 @@
|
||||
#include <asm/hvm/vpt.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/hvm/cacheattr.h>
|
||||
#include <asm/hvm/trace.h>
|
||||
#include <public/sched.h>
|
||||
#include <public/hvm/ioreq.h>
|
||||
#include <public/version.h>
|
||||
@@ -739,15 +740,22 @@ void hvm_send_assist_req(struct vcpu *v)
|
||||
|
||||
void hvm_hlt(unsigned long rflags)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
|
||||
if ( hvm_event_pending(curr) )
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we halt with interrupts disabled, that's a pretty sure sign that we
|
||||
* want to shut down. In a real processor, NMIs are the only way to break
|
||||
* out of this.
|
||||
*/
|
||||
if ( unlikely(!(rflags & X86_EFLAGS_IF)) )
|
||||
return hvm_vcpu_down(current);
|
||||
return hvm_vcpu_down(curr);
|
||||
|
||||
do_sched_op_compat(SCHEDOP_block, 0);
|
||||
|
||||
HVMTRACE_1D(HLT, curr, /* pending = */ vcpu_runnable(curr));
|
||||
}
|
||||
|
||||
void hvm_triple_fault(void)
|
||||
|
||||
@@ -1099,25 +1099,13 @@ static void svm_do_msr_access(struct cpu_user_regs *regs)
|
||||
static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb,
|
||||
struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
struct hvm_intack intack = hvm_vcpu_has_pending_irq(curr);
|
||||
unsigned int inst_len;
|
||||
|
||||
inst_len = __get_instruction_length(curr, INSTR_HLT, NULL);
|
||||
inst_len = __get_instruction_length(current, INSTR_HLT, NULL);
|
||||
if ( inst_len == 0 )
|
||||
return;
|
||||
__update_guest_eip(regs, inst_len);
|
||||
|
||||
/* Check for pending exception or new interrupt. */
|
||||
if ( vmcb->eventinj.fields.v ||
|
||||
((intack.source != hvm_intsrc_none) &&
|
||||
!hvm_interrupt_blocked(current, intack)) )
|
||||
{
|
||||
HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
|
||||
return;
|
||||
}
|
||||
|
||||
HVMTRACE_1D(HLT, curr, /*int pending=*/ 0);
|
||||
hvm_hlt(regs->eflags);
|
||||
}
|
||||
|
||||
|
||||
@@ -1857,22 +1857,6 @@ gp_fault:
|
||||
return X86EMUL_EXCEPTION;
|
||||
}
|
||||
|
||||
static void vmx_do_hlt(struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned long intr_info = __vmread(VM_ENTRY_INTR_INFO);
|
||||
struct vcpu *curr = current;
|
||||
|
||||
/* Check for pending exception. */
|
||||
if ( intr_info & INTR_INFO_VALID_MASK )
|
||||
{
|
||||
HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
|
||||
return;
|
||||
}
|
||||
|
||||
HVMTRACE_1D(HLT, curr, /*int pending=*/ 0);
|
||||
hvm_hlt(regs->eflags);
|
||||
}
|
||||
|
||||
static void vmx_do_extint(struct cpu_user_regs *regs)
|
||||
{
|
||||
unsigned int vector;
|
||||
@@ -2187,7 +2171,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
case EXIT_REASON_HLT:
|
||||
inst_len = __get_instruction_length(); /* Safe: HLT */
|
||||
__update_guest_eip(inst_len);
|
||||
vmx_do_hlt(regs);
|
||||
hvm_hlt(regs->eflags);
|
||||
break;
|
||||
case EXIT_REASON_INVLPG:
|
||||
{
|
||||
|
||||