From patchwork Wed Dec 14 19:38:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Mattson X-Patchwork-Id: 9474555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0A75F60824 for ; Wed, 14 Dec 2016 19:39:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB3C32866E for ; Wed, 14 Dec 2016 19:39:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E04C128685; Wed, 14 Dec 2016 19:39:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76BDC28688 for ; Wed, 14 Dec 2016 19:39:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755901AbcLNTi4 (ORCPT ); Wed, 14 Dec 2016 14:38:56 -0500 Received: from mail-pf0-f172.google.com ([209.85.192.172]:33261 "EHLO mail-pf0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754096AbcLNTiy (ORCPT ); Wed, 14 Dec 2016 14:38:54 -0500 Received: by mail-pf0-f172.google.com with SMTP id d2so5005177pfd.0 for ; Wed, 14 Dec 2016 11:38:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=AlJXf6xi1xgrvBbE4cIngzfuHuxTifsiD0I3AdK05KU=; b=rbECC+dSOuCUk9SJSwJ9QtQ4r8MXYSmGDAabFQQ/6iQW/fAuqzYG332sUYC7g2pbX4 Pd60LbGoXxfZsgFJKDHxqdlz8f783bDaccox67rm02TcziMaiNMoxtZodg+wKP0N0xrG JeAUDDQ3X8UhdbqoYUm4hyoyheCTqCls+MpRzQCAJgmjSiUfQ+nIYtk6rWKiAiq4pw1S l4IpKUasiCwKXlHUzawQZz0v8SCYG2ud8LUxUfopt04RVKQksSwT6K7+p6bcyZl+vTJ9 ljMrNgUhb/t/9XSlv1pk+2MHqh3KiOoeUDqzAiFMP7JCvP5UCeSQgsefJ3tMR36NgQi2 iefA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=AlJXf6xi1xgrvBbE4cIngzfuHuxTifsiD0I3AdK05KU=; b=XuY0bXPke7VlB4io4Ygu6vw2CGrVp7uBr9OBQMWia2CjdrF6om8Y1R56nPsVokGQUd dvI6ApexwNQOM4EaSjJN7ujNPEdtoa0aYzxgKAd4k1CbmwbCvb8HCK4vdGIOA73tB0PF SMbpTWbTOEQkYiYXH8icKLQkft6x2zrp7uWjnZSz0fbKBmFGulg01g+KnfkTI4Ksm9oW UIhrsYer/39m7Or8Bi9i2wkzKEqGWc/oRYa9C2YfOH+ycx/rGUBlD4j8XzZ6gbTCDZ3G /UCWh1wNQvqKQ8lFK4TBTELAc+M63pivKpEUBqI6nVBNOxqOPXJz8g5uxjQnAENp60da jVkQ== X-Gm-Message-State: AKaTC01pyw17e/1DzK4QWCoKBtnA6tMFu1iNWJXlhlc1nRxw1trnuYE3l4Hn8UV6hPgWTzfR X-Received: by 10.98.133.207 with SMTP id m76mr111861842pfk.102.1481744333452; Wed, 14 Dec 2016 11:38:53 -0800 (PST) Received: from jmattson.sea.corp.google.com ([100.100.206.80]) by smtp.gmail.com with ESMTPSA id f3sm52766580pga.45.2016.12.14.11.38.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 14 Dec 2016 11:38:52 -0800 (PST) From: Jim Mattson To: kvm@vger.kernel.org Cc: Jim Mattson Subject: [PATCH kvm-unit-tests] x86/nVMX: Test L1 interception of #BP and #OF in the L2 guest Date: Wed, 14 Dec 2016 11:38:41 -0800 Message-Id: <1481744321-31324-1-git-send-email-jmattson@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Int3 (#BP) and INTO (#OF) are unusual, in that they are reported as "software exception" rather than "hardware exception" in the VM-exit interruption information field of the VMCS. Signed-off-by: Jim Mattson --- lib/x86/processor.h | 5 ++++ x86/vmx.h | 19 ++++++++++++++ x86/vmx_tests.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/lib/x86/processor.h b/lib/x86/processor.h index ee7f180..895d992 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -41,6 +41,11 @@ #define X86_IA32_EFER 0xc0000080 #define X86_EFER_LMA (1UL << 8) +struct far_pointer32 { + u32 offset; + u16 selector; +} __attribute__((packed)); + struct descriptor_table_ptr { u16 limit; ulong base; diff --git a/x86/vmx.h b/x86/vmx.h index 432ffa6..a2bacd3 100644 --- a/x86/vmx.h +++ b/x86/vmx.h @@ -377,6 +377,25 @@ enum Ctrl1 { CPU_RDRAND = 1ul << 11, }; +enum Intr_type { + VMX_INTR_TYPE_EXT_INTR = 0, + VMX_INTR_TYPE_NMI_INTR = 2, + VMX_INTR_TYPE_HARD_EXCEPTION = 3, + VMX_INTR_TYPE_SOFT_INTR = 4, + VMX_INTR_TYPE_SOFT_EXCEPTION = 6, +}; + +/* + * Interruption-information format + */ +#define INTR_INFO_VECTOR_MASK 0xff /* 7:0 */ +#define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ +#define INTR_INFO_DELIVER_CODE_MASK 0x800 /* 11 */ +#define INTR_INFO_UNBLOCK_NMI_MASK 0x1000 /* 12 */ +#define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ + +#define INTR_INFO_INTR_TYPE_SHIFT 8 + #define SAVE_GPR \ "xchg %rax, regs\n\t" \ "xchg %rbx, regs+0x8\n\t" \ diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 5aba999..5fd9570 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -1742,6 +1742,80 @@ static int disable_rdtscp_exit_handler(void) return VMX_TEST_VMEXIT; } +int int3_init() +{ + vmcs_write(EXC_BITMAP, ~0u); + return VMX_TEST_START; +} + +void int3_guest_main() +{ + asm volatile ("int3"); +} + +int int3_exit_handler() +{ + u32 reason = vmcs_read(EXI_REASON); + u32 intr_info = vmcs_read(EXI_INTR_INFO); + + report("L1 intercepts #BP", reason == VMX_EXC_NMI && + (intr_info & INTR_INFO_VALID_MASK) && + (intr_info & INTR_INFO_VECTOR_MASK) == BP_VECTOR && + ((intr_info & INTR_INFO_INTR_TYPE_MASK) >> + INTR_INFO_INTR_TYPE_SHIFT) == VMX_INTR_TYPE_SOFT_EXCEPTION); + + return VMX_TEST_VMEXIT; +} + +int into_init() +{ + vmcs_write(EXC_BITMAP, ~0u); + return VMX_TEST_START; +} + +void into_guest_main() +{ + struct far_pointer32 fp = { + .offset = (uintptr_t)&&into, + .selector = KERNEL_CS32, + }; + register uintptr_t rsp asm("rsp"); + + if (fp.offset != (uintptr_t)&&into) { + printf("Code address too high.\n"); + return; + } + if ((u32)rsp != rsp) { + printf("Stack address too high.\n"); + return; + } + + asm goto ("lcall *%0" : : "m" (fp) : "rax" : into); + return; +into: + asm volatile (".code32;" + "movl $0x7fffffff, %eax;" + "addl %eax, %eax;" + "into;" + "lret;" + ".code64"); + __builtin_unreachable(); +} + +int into_exit_handler() +{ + u32 reason = vmcs_read(EXI_REASON); + u32 intr_info = vmcs_read(EXI_INTR_INFO); + + report("L1 intercepts #OF", reason == VMX_EXC_NMI && + (intr_info & INTR_INFO_VALID_MASK) && + (intr_info & INTR_INFO_VECTOR_MASK) == OF_VECTOR && + ((intr_info & INTR_INFO_INTR_TYPE_MASK) >> + INTR_INFO_INTR_TYPE_SHIFT) == VMX_INTR_TYPE_SOFT_EXCEPTION); + + return VMX_TEST_VMEXIT; +} + /* name/init/guest_main/exit_handler/syscall_handler/guest_regs */ struct vmx_test vmx_tests[] = { { "null", NULL, basic_guest_main, basic_exit_handler, NULL, {0} }, @@ -1769,5 +1843,7 @@ struct vmx_test vmx_tests[] = { { "vmmcall", vmmcall_init, vmmcall_main, vmmcall_exit_handler, NULL, {0} }, { "disable RDTSCP", disable_rdtscp_init, disable_rdtscp_main, disable_rdtscp_exit_handler, NULL, {0} }, + { "int3", int3_init, int3_guest_main, int3_exit_handler, NULL, {0} }, + { "into", into_init, into_guest_main, into_exit_handler, NULL, {0} }, { NULL, NULL, NULL, NULL, NULL, {0} }, };