提交 35a57134 编写于 作者: O Oliver Upton 提交者: Paolo Bonzini

KVM: nVMX: Check IO instruction VM-exit conditions

Consult the 'unconditional IO exiting' and 'use IO bitmaps' VM-execution
controls when checking instruction interception. If the 'use IO bitmaps'
VM-execution control is 1, check the instruction access against the IO
bitmaps to determine if the instruction causes a VM-exit.
Signed-off-by: NOliver Upton <oupton@google.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 e71237d3
...@@ -5353,7 +5353,7 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, ...@@ -5353,7 +5353,7 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
struct vmcs12 *vmcs12) struct vmcs12 *vmcs12)
{ {
unsigned long exit_qualification; unsigned long exit_qualification;
unsigned int port; unsigned short port;
int size; int size;
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
......
...@@ -7145,6 +7145,39 @@ static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu) ...@@ -7145,6 +7145,39 @@ static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu)
to_vmx(vcpu)->req_immediate_exit = true; to_vmx(vcpu)->req_immediate_exit = true;
} }
static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info)
{
struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
unsigned short port;
bool intercept;
int size;
if (info->intercept == x86_intercept_in ||
info->intercept == x86_intercept_ins) {
port = info->src_val;
size = info->dst_bytes;
} else {
port = info->dst_val;
size = info->src_bytes;
}
/*
* If the 'use IO bitmaps' VM-execution control is 0, IO instruction
* VM-exits depend on the 'unconditional IO exiting' VM-execution
* control.
*
* Otherwise, IO instruction VM-exits are controlled by the IO bitmaps.
*/
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
intercept = nested_cpu_has(vmcs12,
CPU_BASED_UNCOND_IO_EXITING);
else
intercept = nested_vmx_check_io_bitmaps(vcpu, port, size);
return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
}
static int vmx_check_intercept(struct kvm_vcpu *vcpu, static int vmx_check_intercept(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info, struct x86_instruction_info *info,
enum x86_intercept_stage stage) enum x86_intercept_stage stage)
...@@ -7152,18 +7185,30 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, ...@@ -7152,18 +7185,30 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
struct vmcs12 *vmcs12 = get_vmcs12(vcpu); struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
switch (info->intercept) {
/* /*
* RDPID causes #UD if disabled through secondary execution controls. * RDPID causes #UD if disabled through secondary execution controls.
* Because it is marked as EmulateOnUD, we need to intercept it here. * Because it is marked as EmulateOnUD, we need to intercept it here.
*/ */
if (info->intercept == x86_intercept_rdtscp && case x86_intercept_rdtscp:
!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
ctxt->exception.vector = UD_VECTOR; ctxt->exception.vector = UD_VECTOR;
ctxt->exception.error_code_valid = false; ctxt->exception.error_code_valid = false;
return X86EMUL_PROPAGATE_FAULT; return X86EMUL_PROPAGATE_FAULT;
} }
break;
case x86_intercept_in:
case x86_intercept_ins:
case x86_intercept_out:
case x86_intercept_outs:
return vmx_check_intercept_io(vcpu, info);
/* TODO: check more intercepts... */ /* TODO: check more intercepts... */
default:
break;
}
return X86EMUL_UNHANDLEABLE; return X86EMUL_UNHANDLEABLE;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册