|
Joerg Roedel |
4072fc |
From: Oliver Upton <oupton@google.com>
|
|
Joerg Roedel |
4072fc |
Date: Tue, 4 Feb 2020 15:26:31 -0800
|
|
Joerg Roedel |
4072fc |
Subject: KVM: nVMX: Check IO instruction VM-exit conditions
|
|
Joerg Roedel |
4072fc |
Git-commit: 35a571346a94fb93b5b3b6a599675ef3384bc75c
|
|
Joerg Roedel |
4072fc |
References: CVE-2020-2732 bsc#1163971
|
|
Joerg Roedel |
4072fc |
Patch-mainline: v5.6-rc4
|
|
Joerg Roedel |
4072fc |
|
|
Joerg Roedel |
4072fc |
Consult the 'unconditional IO exiting' and 'use IO bitmaps' VM-execution
|
|
Joerg Roedel |
4072fc |
controls when checking instruction interception. If the 'use IO bitmaps'
|
|
Joerg Roedel |
4072fc |
VM-execution control is 1, check the instruction access against the IO
|
|
Joerg Roedel |
4072fc |
bitmaps to determine if the instruction causes a VM-exit.
|
|
Joerg Roedel |
4072fc |
|
|
Joerg Roedel |
4072fc |
Signed-off-by: Oliver Upton <oupton@google.com>
|
|
Joerg Roedel |
4072fc |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Joerg Roedel |
4072fc |
Acked-by: Joerg Roedel <jroedel@suse.de>
|
|
Joerg Roedel |
4072fc |
---
|
|
Joerg Roedel |
4072fc |
arch/x86/kvm/vmx/nested.c | 2 +-
|
|
Joerg Roedel |
4072fc |
arch/x86/kvm/vmx/vmx.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
|
|
Joerg Roedel |
4072fc |
2 files changed, 52 insertions(+), 7 deletions(-)
|
|
Joerg Roedel |
4072fc |
|
|
Joerg Roedel |
4072fc |
--- a/arch/x86/kvm/vmx.c
|
|
Joerg Roedel |
4072fc |
+++ b/arch/x86/kvm/vmx.c
|
|
Joerg Roedel |
4072fc |
@@ -8570,7 +8570,7 @@ static bool nested_vmx_exit_handled_io(s
|
|
Joerg Roedel |
4072fc |
struct vmcs12 *vmcs12)
|
|
Joerg Roedel |
4072fc |
{
|
|
Joerg Roedel |
4072fc |
unsigned long exit_qualification;
|
|
Joerg Roedel |
4072fc |
- unsigned int port;
|
|
Joerg Roedel |
4072fc |
+ unsigned short port;
|
|
Joerg Roedel |
4072fc |
int size;
|
|
Joerg Roedel |
4072fc |
|
|
Joerg Roedel |
4072fc |
if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
|
|
Joerg Roedel |
4072fc |
@@ -12386,10 +12386,55 @@ static void nested_vmx_entry_failure(str
|
|
Joerg Roedel |
4072fc |
to_vmx(vcpu)->nested.sync_shadow_vmcs = true;
|
|
Joerg Roedel |
4072fc |
}
|
|
Joerg Roedel |
4072fc |
|
|
Joerg Roedel |
4072fc |
+static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
|
|
Joerg Roedel |
4072fc |
+ struct x86_instruction_info *info)
|
|
Joerg Roedel |
4072fc |
+{
|
|
Joerg Roedel |
4072fc |
+ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
|
|
Joerg Roedel |
4072fc |
+ unsigned short port;
|
|
Joerg Roedel |
4072fc |
+ bool intercept;
|
|
Joerg Roedel |
4072fc |
+ int size;
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
+ if (info->intercept == x86_intercept_in ||
|
|
Joerg Roedel |
4072fc |
+ info->intercept == x86_intercept_ins) {
|
|
Joerg Roedel |
4072fc |
+ port = info->src_val;
|
|
Joerg Roedel |
4072fc |
+ size = info->dst_bytes;
|
|
Joerg Roedel |
4072fc |
+ } else {
|
|
Joerg Roedel |
4072fc |
+ port = info->dst_val;
|
|
Joerg Roedel |
4072fc |
+ size = info->src_bytes;
|
|
Joerg Roedel |
4072fc |
+ }
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
+ /*
|
|
Joerg Roedel |
4072fc |
+ * If the 'use IO bitmaps' VM-execution control is 0, IO instruction
|
|
Joerg Roedel |
4072fc |
+ * VM-exits depend on the 'unconditional IO exiting' VM-execution
|
|
Joerg Roedel |
4072fc |
+ * control.
|
|
Joerg Roedel |
4072fc |
+ *
|
|
Joerg Roedel |
4072fc |
+ * Otherwise, IO instruction VM-exits are controlled by the IO bitmaps.
|
|
Joerg Roedel |
4072fc |
+ */
|
|
Joerg Roedel |
4072fc |
+ if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
|
|
Joerg Roedel |
4072fc |
+ intercept = nested_cpu_has(vmcs12,
|
|
Joerg Roedel |
4072fc |
+ CPU_BASED_UNCOND_IO_EXITING);
|
|
Joerg Roedel |
4072fc |
+ else
|
|
Joerg Roedel |
4072fc |
+ intercept = nested_vmx_check_io_bitmaps(vcpu, port, size);
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
+ return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
|
|
Joerg Roedel |
4072fc |
+}
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
static int vmx_check_intercept(struct kvm_vcpu *vcpu,
|
|
Joerg Roedel |
4072fc |
struct x86_instruction_info *info,
|
|
Joerg Roedel |
4072fc |
enum x86_intercept_stage stage)
|
|
Joerg Roedel |
4072fc |
{
|
|
Joerg Roedel |
4072fc |
+ switch (info->intercept) {
|
|
Joerg Roedel |
4072fc |
+ case x86_intercept_in:
|
|
Joerg Roedel |
4072fc |
+ case x86_intercept_ins:
|
|
Joerg Roedel |
4072fc |
+ case x86_intercept_out:
|
|
Joerg Roedel |
4072fc |
+ case x86_intercept_outs:
|
|
Joerg Roedel |
4072fc |
+ return vmx_check_intercept_io(vcpu, info);
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
+ /* TODO: check more intercepts... */
|
|
Joerg Roedel |
4072fc |
+ default:
|
|
Joerg Roedel |
4072fc |
+ break;
|
|
Joerg Roedel |
4072fc |
+ }
|
|
Joerg Roedel |
4072fc |
+
|
|
Joerg Roedel |
4072fc |
return X86EMUL_UNHANDLEABLE;
|
|
Joerg Roedel |
4072fc |
}
|
|
Joerg Roedel |
4072fc |
|