From patchwork Fri Apr 30 23:24:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12234535 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFF54C433B4 for ; Fri, 30 Apr 2021 23:24:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CD85F6141E for ; Fri, 30 Apr 2021 23:24:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232876AbhD3XZE (ORCPT ); Fri, 30 Apr 2021 19:25:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232860AbhD3XZC (ORCPT ); Fri, 30 Apr 2021 19:25:02 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E465AC06138B for ; Fri, 30 Apr 2021 16:24:12 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id m36-20020a634c640000b02901fbb60ec3a6so25428980pgl.15 for ; Fri, 30 Apr 2021 16:24:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZyjdoDvj+0d1MrdvPreqK5eup22FMf+XNotdYUvQgRI=; b=mVFEcJIz8TqMr35h+/Q4+Dav2KYnjMb7ka5/Gc219hGHhFNsWibr/XuA/YPgX+YHCA NeqV+TgK7Yo40Do4rWs0FSy/f7DQXYjOid3a1piWerc8fAYFMONv/Xny8SzTye5CFkdu 8UO6h2hEwmqxxb/nMC1eCrRL0GCG7JLy8rL2TxB6lsJcFj+nEOnkJ7oqynUSoat7ZCAj axu0v6pjMoecsg8X9qkeuwsozgIWn4HN2ajHRbMCEll5feWXxuNRWaVkgdp/OnOWR817 nwjerzB/XdDGaABVwh7/aFrycJgqzKOIITDywOnNcXrzrlOM/7SnoNQIubrddxI85XBo HOmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZyjdoDvj+0d1MrdvPreqK5eup22FMf+XNotdYUvQgRI=; b=UoM0YqBbSbXk4eMRDo68ZqZ75zZrpzE8wyqfDBCx0tctLZxOtgi7S1UBkjdzDgCKUt FSDTz6YCpeHoOesjiugvo8XayrrJOns/b9tiAhpbM4gXGZsVvJWDtV6fIBE39TAMdebL J2ApHQpS3HRLaKdAOZ/EN4ugsiXsqjf8Kcg6FTDl4b/aF6MiluJujbMxiv43olp4Bujn MApkUtfyrKDQjk3p2ikSnIN0zGW1pYYvZznq4Riylj5s+XC+Ge6so0pKEo4OzD1VIg9p XJjJDxNvoOM/j+43O+l3F37Y9zyeAeSM23KqSRTbByKVVX/zni1ke3Je+dZsbs6qoQow 44Kw== X-Gm-Message-State: AOAM531isKg3ESeNH543nk6tkYJWy3re926PFRNAFr2ewPUPCjEtX9EV SKZH1Ct02/c8xiK/H9EAT5JDXCeHwAa4GfgAqU3+3qME8lqlA3ReksFzUcuv/UUD4nFtnnpNBve uUMm/cGdlIp7NxDyXsiNr9kc90b6qzD5Iadb1xXN9V+DJu3aC4/D+1P/k7eJLwU0= X-Google-Smtp-Source: ABdhPJw/WgOmany3vFjVOVJu6fs2Y1+1Pd0XL579JpPqAIrVqPNcaxkdQAkHOnqSS0bi/PanAPM14cJfMb63Xw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a05:6a00:853:b029:27b:7bf6:f322 with SMTP id q19-20020a056a000853b029027b7bf6f322mr7086773pfk.7.1619825052185; Fri, 30 Apr 2021 16:24:12 -0700 (PDT) Date: Fri, 30 Apr 2021 16:24:03 -0700 In-Reply-To: <20210430232408.2707420-1-ricarkol@google.com> Message-Id: <20210430232408.2707420-2-ricarkol@google.com> Mime-Version: 1.0 References: <20210430232408.2707420-1-ricarkol@google.com> X-Mailer: git-send-email 2.31.1.527.g47e6f16901-goog Subject: [PATCH v2 1/5] KVM: selftests: Rename vm_handle_exception From: Ricardo Koller To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: pbonzini@redhat.com, maz@kernel.org, drjones@redhat.com, alexandru.elisei@arm.com, eric.auger@redhat.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Rename the vm_handle_exception function to a name that indicates more clearly that it installs something: vm_install_vector_handler. Suggested-by: Marc Zyngier Suggested-by: Andrew Jones Signed-off-by: Ricardo Koller Reviewed-by: Andrew Jones Reviewed-by: Eric Auger --- tools/testing/selftests/kvm/include/x86_64/processor.h | 2 +- tools/testing/selftests/kvm/lib/x86_64/processor.c | 4 ++-- tools/testing/selftests/kvm/x86_64/kvm_pv_test.c | 2 +- .../selftests/kvm/x86_64/userspace_msr_exit_test.c | 8 ++++---- tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 0b30b4e15c38..12889d3e8948 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -391,7 +391,7 @@ struct ex_regs { void vm_init_descriptor_tables(struct kvm_vm *vm); void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid); -void vm_handle_exception(struct kvm_vm *vm, int vector, +void vm_install_vector_handler(struct kvm_vm *vm, int vector, void (*handler)(struct ex_regs *)); /* diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index a8906e60a108..e156061263a6 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1250,8 +1250,8 @@ void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid) *(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers; } -void vm_handle_exception(struct kvm_vm *vm, int vector, - void (*handler)(struct ex_regs *)) +void vm_install_vector_handler(struct kvm_vm *vm, int vector, + void (*handler)(struct ex_regs *)) { vm_vaddr_t *handlers = (vm_vaddr_t *)addr_gva2hva(vm, vm->handlers); diff --git a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c index 732b244d6956..5ae5f748723a 100644 --- a/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c +++ b/tools/testing/selftests/kvm/x86_64/kvm_pv_test.c @@ -227,7 +227,7 @@ int main(void) vm_init_descriptor_tables(vm); vcpu_init_descriptor_tables(vm, VCPU_ID); - vm_handle_exception(vm, GP_VECTOR, guest_gp_handler); + vm_install_vector_handler(vm, GP_VECTOR, guest_gp_handler); enter_guest(vm); kvm_vm_free(vm); diff --git a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c b/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c index 72c0d0797522..20c373e2d329 100644 --- a/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c +++ b/tools/testing/selftests/kvm/x86_64/userspace_msr_exit_test.c @@ -574,7 +574,7 @@ static void test_msr_filter_allow(void) { vm_init_descriptor_tables(vm); vcpu_init_descriptor_tables(vm, VCPU_ID); - vm_handle_exception(vm, GP_VECTOR, guest_gp_handler); + vm_install_vector_handler(vm, GP_VECTOR, guest_gp_handler); /* Process guest code userspace exits. */ run_guest_then_process_rdmsr(vm, MSR_IA32_XSS); @@ -588,12 +588,12 @@ static void test_msr_filter_allow(void) { run_guest_then_process_wrmsr(vm, MSR_NON_EXISTENT); run_guest_then_process_rdmsr(vm, MSR_NON_EXISTENT); - vm_handle_exception(vm, UD_VECTOR, guest_ud_handler); + vm_install_vector_handler(vm, UD_VECTOR, guest_ud_handler); run_guest(vm); - vm_handle_exception(vm, UD_VECTOR, NULL); + vm_install_vector_handler(vm, UD_VECTOR, NULL); if (process_ucall(vm) != UCALL_DONE) { - vm_handle_exception(vm, GP_VECTOR, guest_fep_gp_handler); + vm_install_vector_handler(vm, GP_VECTOR, guest_fep_gp_handler); /* Process emulated rdmsr and wrmsr instructions. */ run_guest_then_process_rdmsr(vm, MSR_IA32_XSS); diff --git a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c b/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c index 2f964cdc273c..ded70ff465d5 100644 --- a/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c +++ b/tools/testing/selftests/kvm/x86_64/xapic_ipi_test.c @@ -462,7 +462,7 @@ int main(int argc, char *argv[]) vm_init_descriptor_tables(vm); vcpu_init_descriptor_tables(vm, HALTER_VCPU_ID); - vm_handle_exception(vm, IPI_VECTOR, guest_ipi_handler); + vm_install_vector_handler(vm, IPI_VECTOR, guest_ipi_handler); virt_pg_map(vm, APIC_DEFAULT_GPA, APIC_DEFAULT_GPA, 0); From patchwork Fri Apr 30 23:24:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12234537 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70D6CC433ED for ; Fri, 30 Apr 2021 23:24:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 522BC61418 for ; Fri, 30 Apr 2021 23:24:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232880AbhD3XZE (ORCPT ); Fri, 30 Apr 2021 19:25:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232861AbhD3XZD (ORCPT ); Fri, 30 Apr 2021 19:25:03 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C1C18C06174A for ; Fri, 30 Apr 2021 16:24:14 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id r2-20020a25ac420000b02904f5a9b7d37fso834807ybd.22 for ; Fri, 30 Apr 2021 16:24:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DrtIzoZNc79OT7R03r+6Yhv7XXgWtVPXBdQ8gE5Za50=; b=hrA93mrfNvMtPI4VgsoEAfSKtto6rMPg+XTcD8MyoMUgLaj5o9tLH3AwvT5hgfwWoZ etFwv7KD1vg1aRcGGpw5PRSmKq0tE7WHqERR0XauYivNrLYKmOMuupUwQSfEtWMh08r7 cihPWH3QFt9w3b/V5DeidqkD26w13mLIzcyk41Ym+dhZEgIB0D9x5VVCS+lVeGLOkMhD gaP8C7S9g51MowvglkvRjiDYjSssCj4VTPEz6dLV2SIIkDSRr6L80gCz1m98goVOv9hq bem2O7Q/hq4UwAFPSw7yjYDMgsjtpCd+KOA/kjvaSRPKIuZorYXLQ7D3DugljqjU1d5q 96Dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DrtIzoZNc79OT7R03r+6Yhv7XXgWtVPXBdQ8gE5Za50=; b=hfVIvBM0+IIVU2qRLsGO2vYNJwb+njfxJUPVdMo5vL1Cmus1bDX5VehNnXbu5W9U2i CRvbUJHgMwKBCJktjB85lZQOQCuSfidqnoroW9qrL3skHxXGlXt70dZGkuIvnCNO1Atg YlXJfemUQPL2q95X4ZL27D2OCOI3Bq88YvMTjIcPs/gbqVB8g9mWlmn/nTLVd74pthpD jGcrnczvXvkj/cH39MCOfCBqhslUW/ZfR9Y4ZGo4k33aakdJKz6kusXecETFBtQF+8qj CjuSQ3fy9Ghu0NxTe+LDzYtgxTfwzjXv7n+aKjOin5BcvjJ6JYunvsjSIzTftKgya+YL DE7A== X-Gm-Message-State: AOAM531wXLdAfXgJ+s8Yql8ZKTGZ+smX5wof8i5ZN474P6jDLbjWO+1z nzRgvPQjvEWCMBpnJd7uyuWtRzBnEK/hVK1ZOKMU97UnGGL1wPEuevdcloUNuGTBG/A0wH1369X Rje0bwF7vV7HJbmiOLjSyszMbCpo33PnXKvBUql3YU2BZJkhJ1A30oO3hMwvHPiM= X-Google-Smtp-Source: ABdhPJxCH47qwg6o/sPFrCh0eBsljgWhHVIlR+rd2tL+C+5G+0C/awiKqu15PVkzt+chVmExB8oH4/OW2Cw2GQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a25:6d82:: with SMTP id i124mr10969252ybc.78.1619825053901; Fri, 30 Apr 2021 16:24:13 -0700 (PDT) Date: Fri, 30 Apr 2021 16:24:04 -0700 In-Reply-To: <20210430232408.2707420-1-ricarkol@google.com> Message-Id: <20210430232408.2707420-3-ricarkol@google.com> Mime-Version: 1.0 References: <20210430232408.2707420-1-ricarkol@google.com> X-Mailer: git-send-email 2.31.1.527.g47e6f16901-goog Subject: [PATCH v2 2/5] KVM: selftests: Introduce UCALL_UNHANDLED for unhandled vector reporting From: Ricardo Koller To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: pbonzini@redhat.com, maz@kernel.org, drjones@redhat.com, alexandru.elisei@arm.com, eric.auger@redhat.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org x86, the only arch implementing exception handling, reports unhandled vectors using port IO at a specific port number. This replicates what ucall already does. Introduce a new ucall type, UCALL_UNHANDLED, for guests to report unhandled exceptions. Then replace the x86 unhandled vector exception reporting to use it instead of port IO. This new ucall type will be used in the next commits by arm64 to report unhandled vectors as well. Tested: Forcing a page fault in the ./x86_64/xapic_ipi_test halter_guest_code() shows this: $ ./x86_64/xapic_ipi_test ... Unexpected vectored event in guest (vector:0xe) Signed-off-by: Ricardo Koller Reviewed-by: Andrew Jones Reviewed-by: Eric Auger --- tools/testing/selftests/kvm/include/kvm_util.h | 1 + .../selftests/kvm/include/x86_64/processor.h | 2 -- .../testing/selftests/kvm/lib/x86_64/processor.c | 15 ++++++--------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index bea4644d645d..7880929ea548 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -347,6 +347,7 @@ enum { UCALL_SYNC, UCALL_ABORT, UCALL_DONE, + UCALL_UNHANDLED, }; #define UCALL_MAX_ARGS 6 diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 12889d3e8948..ff4da2f95b13 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -53,8 +53,6 @@ #define CPUID_PKU (1ul << 3) #define CPUID_LA57 (1ul << 16) -#define UNEXPECTED_VECTOR_PORT 0xfff0u - /* General Registers in 64-Bit Mode */ struct gpr64_regs { u64 rax; diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index e156061263a6..96e2bd9d66eb 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -1207,7 +1207,7 @@ static void set_idt_entry(struct kvm_vm *vm, int vector, unsigned long addr, void kvm_exit_unexpected_vector(uint32_t value) { - outl(UNEXPECTED_VECTOR_PORT, value); + ucall(UCALL_UNHANDLED, 1, value); } void route_exception(struct ex_regs *regs) @@ -1260,16 +1260,13 @@ void vm_install_vector_handler(struct kvm_vm *vm, int vector, void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid) { - if (vcpu_state(vm, vcpuid)->exit_reason == KVM_EXIT_IO - && vcpu_state(vm, vcpuid)->io.port == UNEXPECTED_VECTOR_PORT - && vcpu_state(vm, vcpuid)->io.size == 4) { - /* Grab pointer to io data */ - uint32_t *data = (void *)vcpu_state(vm, vcpuid) - + vcpu_state(vm, vcpuid)->io.data_offset; + struct ucall uc; + if (get_ucall(vm, vcpuid, &uc) == UCALL_UNHANDLED) { + uint64_t vector = uc.args[0]; TEST_ASSERT(false, - "Unexpected vectored event in guest (vector:0x%x)", - *data); + "Unexpected vectored event in guest (vector:0x%lx)", + vector); } } From patchwork Fri Apr 30 23:24:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12234539 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE400C43462 for ; Fri, 30 Apr 2021 23:24:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CEA816140C for ; Fri, 30 Apr 2021 23:24:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232890AbhD3XZG (ORCPT ); Fri, 30 Apr 2021 19:25:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232861AbhD3XZF (ORCPT ); Fri, 30 Apr 2021 19:25:05 -0400 Received: from mail-pf1-x449.google.com (mail-pf1-x449.google.com [IPv6:2607:f8b0:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9897C06174A for ; Fri, 30 Apr 2021 16:24:15 -0700 (PDT) Received: by mail-pf1-x449.google.com with SMTP id 9-20020a056a000729b029025d0d3c2062so146205pfm.1 for ; Fri, 30 Apr 2021 16:24:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=+DSPnKtKLaCWYruB9RUFpApCJLw7ci5vJYpmKsxCMpY=; b=GHmtm/HM2OsR4qjLE/kzZOFZvHz4TWk6oZ3ISonugQE6amsbiSELaSSMwNq1EmIKhD dlftmhUu0LrDTzlEUbYbo7zrpSF89uaN24YRWR4BBjiUaG44gV9W5Akqw+fPwnSngtUV vvrLatZTJP5fXD8VrPgRQFP1Zml58ooiVF7NdK0+e4dCErXUfJjk4IC1v5q2H4PQjjNd nztXvIOclQ/qwp6OkK+R35UH+ZXmMTdf36MXFViViWfnIYPrpFBncFkkcaGUptG7WPL+ KJK0kR5vRn7Fpz9JKPs9IqiTc6AW727iV7E4+zFBAxPc70hIB4Kcpge+JFoEDo2Z7m6g L+TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=+DSPnKtKLaCWYruB9RUFpApCJLw7ci5vJYpmKsxCMpY=; b=liIn5uXVX+RznSVqQPq8awQpU9WCD3rbwo9jkAtHJZyhBsImIg0yQk44IQa+TGYjmN 9TkJH0dFNssNq6mhNtfNN3OLWjHmVsiQF5EmtJeIclQnnbjaSlXDwUItlNduA0ayQCul DHY+vMTmXHWMF0I3/UGFeUY+hZgllq2eBabKmJGUR6V8uRLPC5NKQcJ6CiJ9yvSttV/8 k5fXEsRvlu7Rvrw5pGBDTDwJnhCVgvOpZxivXZZlCn1C8EKf9nWtHIIwkOXehYNwxw+X UtgSQB7ikacQBYO5jBFSG3fWCsSiIj/dkasexz/7xiO5JR9YEwnOk1WHbkcIiHn3qxmj 7T1Q== X-Gm-Message-State: AOAM531uy4x0lwSwjq1hugFzM8a7ZLMLDMfj6Na/+6CqBPNXqoxEpPMR 9C+Fans1q6o8NzHO2Oncw6VpIDoKn8CuHasw7EJKE4Ikoo3W2QDPnqLTEWztvSfUDuFjPw/JwUD 3S4HUmQoSyDytngtEm7FacWJeNIHbXGptuRYZR+EavcwZwOnKaJR8u+Ivu7KJhpM= X-Google-Smtp-Source: ABdhPJwC5V/hbECRi8QXjzfu3qwYiwVszsZ2QtYnlFZCKfIcZmSzuCJ4ZAqv7NpufKqwn6hZrHJb7GOdJFz6fQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:b905:b029:ed:2235:ad2c with SMTP id bf5-20020a170902b905b02900ed2235ad2cmr7763186plb.28.1619825055219; Fri, 30 Apr 2021 16:24:15 -0700 (PDT) Date: Fri, 30 Apr 2021 16:24:05 -0700 In-Reply-To: <20210430232408.2707420-1-ricarkol@google.com> Message-Id: <20210430232408.2707420-4-ricarkol@google.com> Mime-Version: 1.0 References: <20210430232408.2707420-1-ricarkol@google.com> X-Mailer: git-send-email 2.31.1.527.g47e6f16901-goog Subject: [PATCH v2 3/5] KVM: selftests: Move GUEST_ASSERT_EQ to utils header From: Ricardo Koller To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: pbonzini@redhat.com, maz@kernel.org, drjones@redhat.com, alexandru.elisei@arm.com, eric.auger@redhat.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move GUEST_ASSERT_EQ to a common header, kvm_util.h, for other architectures and tests to use. Signed-off-by: Ricardo Koller --- tools/testing/selftests/kvm/include/kvm_util.h | 9 +++++++++ tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 7880929ea548..bd26dd93ab56 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -388,4 +388,13 @@ uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc); #define GUEST_ASSERT_4(_condition, arg1, arg2, arg3, arg4) \ __GUEST_ASSERT((_condition), 4, (arg1), (arg2), (arg3), (arg4)) +#define GUEST_ASSERT_EQ(a, b) do { \ + __typeof(a) _a = (a); \ + __typeof(b) _b = (b); \ + if (_a != _b) \ + ucall(UCALL_ABORT, 4, \ + "Failed guest assert: " \ + #a " == " #b, __LINE__, _a, _b); \ +} while(0) + #endif /* SELFTEST_KVM_UTIL_H */ diff --git a/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c b/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c index e357d8e222d4..5a6a662f2e59 100644 --- a/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c +++ b/tools/testing/selftests/kvm/x86_64/tsc_msrs_test.c @@ -18,15 +18,6 @@ #define rounded_rdmsr(x) ROUND(rdmsr(x)) #define rounded_host_rdmsr(x) ROUND(vcpu_get_msr(vm, 0, x)) -#define GUEST_ASSERT_EQ(a, b) do { \ - __typeof(a) _a = (a); \ - __typeof(b) _b = (b); \ - if (_a != _b) \ - ucall(UCALL_ABORT, 4, \ - "Failed guest assert: " \ - #a " == " #b, __LINE__, _a, _b); \ - } while(0) - static void guest_code(void) { u64 val = 0; From patchwork Fri Apr 30 23:24:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12234541 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36DEEC433ED for ; Fri, 30 Apr 2021 23:24:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 14FB161418 for ; Fri, 30 Apr 2021 23:24:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232919AbhD3XZJ (ORCPT ); Fri, 30 Apr 2021 19:25:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52332 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232894AbhD3XZH (ORCPT ); Fri, 30 Apr 2021 19:25:07 -0400 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DBF27C06138B for ; Fri, 30 Apr 2021 16:24:17 -0700 (PDT) Received: by mail-qt1-x84a.google.com with SMTP id g21-20020ac858150000b02901ba6163708bso20327214qtg.5 for ; Fri, 30 Apr 2021 16:24:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=uF8yDOKUA0vCPjqru2YZD2b1FQ7m45/wQy2aMMhXwew=; b=OYtqSQSV+jriGqzeAhZdYco1ZvVdXpEugKBlyIjNvWzbXJ510vwITWf+0M2Ts5IjTh peilEEKW0ho5bcduqowCHxfsGJDXCKwWt8VdSIpFI/exnoXfnOaROYMhaDUjk7kJxPqW xusCe9MMkNkI4gbZcn7Hp9Vyh6HQf/RHqTzc0GT26PcmGNhmE4KeZgome9+yGzuPizf3 8RN+jgEV9HkXJjrVNzvntvQEyIu+XhPofrpbhhE9rNsrldIrFtQQmfL7lohnHppcDIU2 KF52f/ubA829KIjvFNkG7Y3i0tzzDEoxGDbIigqFTNhXhqY5GJ/lz0VxP6IQzfMrIqPK ygGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=uF8yDOKUA0vCPjqru2YZD2b1FQ7m45/wQy2aMMhXwew=; b=R7gFmquyUmm4Z6MccwzNwiq4pLnfN7RetV+Q4qsbkuyioPUakZrRZuvjEFqrmonkf2 FuIen2gR/oE3R7hJ1ah6mW8Vj1fFcSBti1Zyav3aCtNJBNEq67r5l6S6g0NAKmubjz5D /RuxD6uNS+9S6aNV/adGSJkNt+Rb9GoBaNohTmUNKKZWnqeZ14+ykTqQFSHX/zshzHZj RFsPeQyKIDYi0oxIuzkFuBeRnjh82a84t3DtxDmwdfvSb9/bV8i9By17DMAI8++3iYkj 2OWqf53LK8rz1Eduqf0dkWvbfDwo6tsON8ctUxpC4aiBdoIkKFzWCRhOJV9bw7ePtM15 G5Iw== X-Gm-Message-State: AOAM531TQT/gm5IFtNL3zjatN3eZUKatXtbnWQBlKKr6ukqH+qcGi2Nw HQaL3cqUbqCm3RTj2vfzo+i8cWlAd0GoXXVspJ+lBXxu6DWItDNhV9x35BC12a1Km6RdwW+D3TS S2z0nJr7k4st1MM1c7c1X/z70DfFXBZjdd05oMXKZL6QWDyNIUEZkLDaz1o9oJas= X-Google-Smtp-Source: ABdhPJwo277EEhAqvm3p7vN0FxX5Rhqv06LjwuXtG8asjRTcmTpNae1YNnTi556c5swP3QyVxSsi0C+QBwr/pQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a0c:a283:: with SMTP id g3mr7935364qva.15.1619825056771; Fri, 30 Apr 2021 16:24:16 -0700 (PDT) Date: Fri, 30 Apr 2021 16:24:06 -0700 In-Reply-To: <20210430232408.2707420-1-ricarkol@google.com> Message-Id: <20210430232408.2707420-5-ricarkol@google.com> Mime-Version: 1.0 References: <20210430232408.2707420-1-ricarkol@google.com> X-Mailer: git-send-email 2.31.1.527.g47e6f16901-goog Subject: [PATCH v2 4/5] KVM: selftests: Add exception handling support for aarch64 From: Ricardo Koller To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: pbonzini@redhat.com, maz@kernel.org, drjones@redhat.com, alexandru.elisei@arm.com, eric.auger@redhat.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add the infrastructure needed to enable exception handling in aarch64 selftests. The exception handling defaults to an unhandled-exception handler which aborts the test, just like x86. These handlers can be overridden by calling vm_install_vector_handler(vector) or vm_install_exception_handler(vector, ec). The unhandled exception reporting from the guest is done using the ucall type introduced in a previous commit, UCALL_UNHANDLED. The exception handling code is heavily inspired on kvm-unit-tests. Signed-off-by: Ricardo Koller --- tools/testing/selftests/kvm/Makefile | 2 +- .../selftests/kvm/include/aarch64/processor.h | 78 +++++++++++ .../selftests/kvm/lib/aarch64/handlers.S | 130 ++++++++++++++++++ .../selftests/kvm/lib/aarch64/processor.c | 124 +++++++++++++++++ 4 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/kvm/lib/aarch64/handlers.S diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 4e548d7ab0ab..618c5903f478 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -35,7 +35,7 @@ endif LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c lib/test_util.c lib/guest_modes.c lib/perf_test_util.c LIBKVM_x86_64 = lib/x86_64/processor.c lib/x86_64/vmx.c lib/x86_64/svm.c lib/x86_64/ucall.c lib/x86_64/handlers.S -LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c +LIBKVM_aarch64 = lib/aarch64/processor.c lib/aarch64/ucall.c lib/aarch64/handlers.S LIBKVM_s390x = lib/s390x/processor.c lib/s390x/ucall.c lib/s390x/diag318_test_handler.c TEST_GEN_PROGS_x86_64 = x86_64/cr4_cpuid_sync_test diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index b7fa0c8551db..40aae31b4afc 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -8,6 +8,7 @@ #define SELFTEST_KVM_PROCESSOR_H #include "kvm_util.h" +#include #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ @@ -18,6 +19,7 @@ #define MAIR_EL1 3, 0, 10, 2, 0 #define TTBR0_EL1 3, 0, 2, 0, 0 #define SCTLR_EL1 3, 0, 1, 0, 0 +#define VBAR_EL1 3, 0, 12, 0, 0 /* * Default MAIR @@ -56,4 +58,80 @@ void aarch64_vcpu_setup(struct kvm_vm *vm, int vcpuid, struct kvm_vcpu_init *ini void aarch64_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_vcpu_init *init, void *guest_code); +struct ex_regs { + u64 regs[31]; + u64 sp; + u64 pc; + u64 pstate; +}; + +#define VECTOR_NUM 16 + +enum { + VECTOR_SYNC_CURRENT_SP0, + VECTOR_IRQ_CURRENT_SP0, + VECTOR_FIQ_CURRENT_SP0, + VECTOR_ERROR_CURRENT_SP0, + + VECTOR_SYNC_CURRENT, + VECTOR_IRQ_CURRENT, + VECTOR_FIQ_CURRENT, + VECTOR_ERROR_CURRENT, + + VECTOR_SYNC_LOWER_64, + VECTOR_IRQ_LOWER_64, + VECTOR_FIQ_LOWER_64, + VECTOR_ERROR_LOWER_64, + + VECTOR_SYNC_LOWER_32, + VECTOR_IRQ_LOWER_32, + VECTOR_FIQ_LOWER_32, + VECTOR_ERROR_LOWER_32, +}; + +#define VECTOR_IS_SYNC(v) ((v) == VECTOR_SYNC_CURRENT_SP0 || \ + (v) == VECTOR_SYNC_CURRENT || \ + (v) == VECTOR_SYNC_LOWER_64 || \ + (v) == VECTOR_SYNC_LOWER_32) + +/* Some common EC (Exception classes) */ +#define ESR_EC_ILLEGAL_INS 0x0e +#define ESR_EC_SVC64 0x15 +#define ESR_EC_IABORT_CURRENT 0x21 +#define ESR_EC_DABORT_CURRENT 0x25 +#define ESR_EC_SERROR 0x2f +#define ESR_EC_HW_BP_CURRENT 0x31 +#define ESR_EC_SSTEP_CURRENT 0x33 +#define ESR_EC_WP_CURRENT 0x35 +#define ESR_EC_BRK_INS 0x3C + +#define ESR_EC_NUM 64 + +#define ESR_EC_SHIFT 26 +#define ESR_EC_MASK (ESR_EC_NUM - 1) + +void vm_init_descriptor_tables(struct kvm_vm *vm); +void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid); + +typedef void(*handler_fn)(struct ex_regs *); +void vm_install_exception_handler(struct kvm_vm *vm, + int vector, int ec, handler_fn handler); +void vm_install_vector_handler(struct kvm_vm *vm, + int vector, handler_fn handler); + +#define SPSR_D (1 << 9) +#define SPSR_SS (1 << 21) + +#define write_sysreg(reg, val) \ +({ \ + u64 __val = (u64)(val); \ + asm volatile("msr " __stringify(reg) ", %x0" : : "rZ" (__val)); \ +}) + +#define read_sysreg(reg) \ +({ u64 val; \ + asm volatile("mrs %0, "__stringify(reg) : "=r"(val) : : "memory");\ + val; \ +}) + #endif /* SELFTEST_KVM_PROCESSOR_H */ diff --git a/tools/testing/selftests/kvm/lib/aarch64/handlers.S b/tools/testing/selftests/kvm/lib/aarch64/handlers.S new file mode 100644 index 000000000000..8a560021892b --- /dev/null +++ b/tools/testing/selftests/kvm/lib/aarch64/handlers.S @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +.macro save_registers, vector + add sp, sp, #-16 * 17 + + stp x0, x1, [sp, #16 * 0] + stp x2, x3, [sp, #16 * 1] + stp x4, x5, [sp, #16 * 2] + stp x6, x7, [sp, #16 * 3] + stp x8, x9, [sp, #16 * 4] + stp x10, x11, [sp, #16 * 5] + stp x12, x13, [sp, #16 * 6] + stp x14, x15, [sp, #16 * 7] + stp x16, x17, [sp, #16 * 8] + stp x18, x19, [sp, #16 * 9] + stp x20, x21, [sp, #16 * 10] + stp x22, x23, [sp, #16 * 11] + stp x24, x25, [sp, #16 * 12] + stp x26, x27, [sp, #16 * 13] + stp x28, x29, [sp, #16 * 14] + + .if \vector >= 8 + mrs x1, sp_el0 + .else + /* + * This stores sp_el1 into ex_regs.sp so exception handlers can + * "look" at it. It will _not_ be used to restore the sp_el1 on + * return from the exception so handlers can not update it. + */ + mov x1, sp + .endif + stp x30, x1, [sp, #16 * 15] /* x30, SP */ + + mrs x1, elr_el1 + mrs x2, spsr_el1 + stp x1, x2, [sp, #16 * 16] /* PC, PSTATE */ +.endm + +.macro restore_registers, vector + ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */ + msr elr_el1, x1 + msr spsr_el1, x2 + + ldp x30, x1, [sp, #16 * 15] /* x30, SP */ + .if \vector >= 8 + msr sp_el0, x1 + .endif + + ldp x28, x29, [sp, #16 * 14] + ldp x26, x27, [sp, #16 * 13] + ldp x24, x25, [sp, #16 * 12] + ldp x22, x23, [sp, #16 * 11] + ldp x20, x21, [sp, #16 * 10] + ldp x18, x19, [sp, #16 * 9] + ldp x16, x17, [sp, #16 * 8] + ldp x14, x15, [sp, #16 * 7] + ldp x12, x13, [sp, #16 * 6] + ldp x10, x11, [sp, #16 * 5] + ldp x8, x9, [sp, #16 * 4] + ldp x6, x7, [sp, #16 * 3] + ldp x4, x5, [sp, #16 * 2] + ldp x2, x3, [sp, #16 * 1] + ldp x0, x1, [sp, #16 * 0] + + add sp, sp, #16 * 17 + + eret +.endm + +.pushsection ".entry.text", "ax" +.balign 0x800 +.global vectors +vectors: +.popsection + +.set vector, 0 + +/* + * Build an exception handler for vector and append a jump to it into + * vectors (while making sure that it's 0x80 aligned). + */ +.macro HANDLER, label +handler_\()\label: + save_registers vector + mov x0, sp + mov x1, #vector + bl route_exception + restore_registers vector + +.pushsection ".entry.text", "ax" +.balign 0x80 + b handler_\()\label +.popsection + +.set vector, vector + 1 +.endm + +.macro HANDLER_INVALID +.pushsection ".entry.text", "ax" +.balign 0x80 +/* This will abort so no need to save and restore registers. */ + mov x0, #vector + b kvm_exit_unexpected_vector +.popsection + +.set vector, vector + 1 +.endm + +/* + * Caution: be sure to not add anything between the declaration of vectors + * above and these macro calls that will build the vectors table below it. + */ + HANDLER_INVALID // Synchronous EL1t + HANDLER_INVALID // IRQ EL1t + HANDLER_INVALID // FIQ EL1t + HANDLER_INVALID // Error EL1t + + HANDLER el1h_sync // Synchronous EL1h + HANDLER el1h_irq // IRQ EL1h + HANDLER el1h_fiq // FIQ EL1h + HANDLER el1h_error // Error EL1h + + HANDLER el0_sync_64 // Synchronous 64-bit EL0 + HANDLER el0_irq_64 // IRQ 64-bit EL0 + HANDLER el0_fiq_64 // FIQ 64-bit EL0 + HANDLER el0_error_64 // Error 64-bit EL0 + + HANDLER el0_sync_32 // Synchronous 32-bit EL0 + HANDLER el0_irq_32 // IRQ 32-bit EL0 + HANDLER el0_fiq_32 // FIQ 32-bit EL0 + HANDLER el0_error_32 // Error 32-bit EL0 diff --git a/tools/testing/selftests/kvm/lib/aarch64/processor.c b/tools/testing/selftests/kvm/lib/aarch64/processor.c index cee92d477dc0..25be71ec88be 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/processor.c +++ b/tools/testing/selftests/kvm/lib/aarch64/processor.c @@ -6,6 +6,7 @@ */ #include +#include #include "kvm_util.h" #include "../kvm_util_internal.h" @@ -14,6 +15,8 @@ #define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000 #define DEFAULT_ARM64_GUEST_STACK_VADDR_MIN 0xac0000 +vm_vaddr_t exception_handlers; + static uint64_t page_align(struct kvm_vm *vm, uint64_t v) { return (v + vm->page_size) & ~(vm->page_size - 1); @@ -334,6 +337,127 @@ void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...) va_end(ap); } +void kvm_exit_unexpected_vector(int vector) +{ + ucall(UCALL_UNHANDLED, 3, vector, 0, false /* !valid_ec */); +} + +void kvm_exit_unexpected_exception(int vector, uint64_t ec) +{ + ucall(UCALL_UNHANDLED, 3, vector, ec, true /* valid_ec */); +} + void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid) { + struct ucall uc; + + if (get_ucall(vm, vcpuid, &uc) != UCALL_UNHANDLED) + return; + + if (uc.args[2]) /* valid_ec */ { + assert(VECTOR_IS_SYNC(uc.args[0])); + TEST_ASSERT(false, + "Unexpected exception (vector:0x%lx, ec:0x%lx)", + uc.args[0], uc.args[1]); + } else { + assert(!VECTOR_IS_SYNC(uc.args[0])); + TEST_ASSERT(false, + "Unexpected exception (vector:0x%lx)", + uc.args[0]); + } +} + +/* + * This exception handling code was heavily inspired on kvm-unit-tests. There + * is a set of default vector handlers stored in vector_handlers. These default + * vector handlers call user-installed handlers stored in exception_handlers. + * Synchronous handlers are indexed by (vector, ec), and irq handlers by + * (vector, ec=0). + */ + +typedef void(*vector_fn)(struct ex_regs *, int vector); + +struct handlers { + vector_fn vector_handlers[VECTOR_NUM]; + handler_fn exception_handlers[VECTOR_NUM][ESR_EC_NUM]; +}; + +void vcpu_init_descriptor_tables(struct kvm_vm *vm, uint32_t vcpuid) +{ + extern char vectors; + + set_reg(vm, vcpuid, ARM64_SYS_REG(VBAR_EL1), (uint64_t)&vectors); +} + +void default_sync_handler(struct ex_regs *regs, int vector) +{ + struct handlers *handlers = (struct handlers *)exception_handlers; + uint64_t esr = read_sysreg(esr_el1); + uint64_t ec = (esr >> ESR_EC_SHIFT) & ESR_EC_MASK; + + GUEST_ASSERT(VECTOR_IS_SYNC(vector)); + + if (handlers && handlers->exception_handlers[vector][ec]) + handlers->exception_handlers[vector][ec](regs); + else + kvm_exit_unexpected_exception(vector, ec); +} + +void default_irq_handler(struct ex_regs *regs, int vector) +{ + struct handlers *handlers = (struct handlers *)exception_handlers; + + GUEST_ASSERT(!VECTOR_IS_SYNC(vector)); + + if (handlers && handlers->exception_handlers[vector][0]) + handlers->exception_handlers[vector][0](regs); + else + kvm_exit_unexpected_vector(vector); +} + +void route_exception(struct ex_regs *regs, int vector) +{ + struct handlers *handlers = (struct handlers *)exception_handlers; + + if (handlers && handlers->vector_handlers[vector]) + handlers->vector_handlers[vector](regs, vector); + else + kvm_exit_unexpected_vector(vector); +} + +void vm_init_descriptor_tables(struct kvm_vm *vm) +{ + struct handlers *handlers; + + vm->handlers = vm_vaddr_alloc(vm, sizeof(struct handlers), + vm->page_size, 0, 0); + + handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers); + handlers->vector_handlers[VECTOR_SYNC_CURRENT] = default_sync_handler; + handlers->vector_handlers[VECTOR_IRQ_CURRENT] = default_irq_handler; + handlers->vector_handlers[VECTOR_SYNC_LOWER_64] = default_sync_handler; + handlers->vector_handlers[VECTOR_IRQ_LOWER_64] = default_irq_handler; + + *(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers; +} + +void vm_install_exception_handler(struct kvm_vm *vm, int vector, int ec, + void (*handler)(struct ex_regs *)) +{ + struct handlers *handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers); + + assert(VECTOR_IS_SYNC(vector)); + assert(vector < VECTOR_NUM); + assert(ec < ESR_EC_NUM); + handlers->exception_handlers[vector][ec] = handler; +} + +void vm_install_vector_handler(struct kvm_vm *vm, int vector, + void (*handler)(struct ex_regs *)) +{ + struct handlers *handlers = (struct handlers *)addr_gva2hva(vm, vm->handlers); + + assert(!VECTOR_IS_SYNC(vector)); + assert(vector < VECTOR_NUM); + handlers->exception_handlers[vector][0] = handler; } From patchwork Fri Apr 30 23:24:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12234543 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-26.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25793C433B4 for ; Fri, 30 Apr 2021 23:24:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 076B86142A for ; Fri, 30 Apr 2021 23:24:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232916AbhD3XZJ (ORCPT ); Fri, 30 Apr 2021 19:25:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232913AbhD3XZI (ORCPT ); Fri, 30 Apr 2021 19:25:08 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 04AF6C06138C for ; Fri, 30 Apr 2021 16:24:19 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id m68-20020a6326470000b029020f37ad2901so4236418pgm.7 for ; Fri, 30 Apr 2021 16:24:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=CHatLD5Tl1lQJpmZw15smommPJOJbCh71D4e3ytfPPM=; b=LsaA1Zdru8LDIWkutXfR0M+1JQaI6nR3ERROJfusNV8jG9Jdnuyh6QBsHP66RxdymB 2fDPdGwnAqkjHj8Q+auocilZp6lr226veLKd1NUGvM7JRaDxxhJLNE9gcPcv36I3Ir8S 36b75n62rb+3mUfcsQJB2vpqocaWuXYG5JRr++evzEGUZ8lPCFkQRm0VGr/KHl0rjtFU SlWMNCfLIvVebiGreX1jVxCTrUTjruWxrq35v8huRCwmrOvhvwe5wU4+a5Hw5Nct8fXn KZHSNPO5GR9wAQ7geHhpeC5uVeVph03jNvLBGHGG9FL4hoizQh9McpNpsSmSpc7q5+Mh yj+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=CHatLD5Tl1lQJpmZw15smommPJOJbCh71D4e3ytfPPM=; b=CMB2LyHbHdrymIgHUKMtawlCWAjfCBM4yCWVctepnI+LTP3IVcyI+gNtUAXikxcLDc 67VxFC820fYTuTVqwuFLAfTtL2B8zgVF9jRklSHJ2LgqIwBK+Oc5NOmhAofyWYFi3ETQ KUXSmNl35s7JdivWbp3SL3VWg13XxUQP3Ve0XPy+YaFQvIW2q1EFpDy6DhEAQ668C3Qe kvfHB6tfBNVXplFIRWFAvpB4hm+Pa3HgMxfi9UmAcj7vuqI4+u2fzJEYF0J7XJ8+CmWF AXawkh0S+X8hmmrUJtk1qUnyq2r6AOKPqDWsqSNOnnFp9sgst9C2BW8B55F+RtGEWyd1 exQA== X-Gm-Message-State: AOAM530TvGpkQHevKTqIB8BtahBGp5MsGyGHri04085fRQ91QzRePxjw XEV6fKVpHnb7JwNdVSEP8svqnjkqn7NK25KzeCVgK9CzUvby4EbANq6IoEfgK/IrlrsziQksBK/ y+JiiPS5EABuSCVyzPnFhna1QJyfxZ/9NTDAkWHli7wEa+CN9NqZAx2ZUuTY4FiQ= X-Google-Smtp-Source: ABdhPJwfRBRfmVe1PvF+YWxvfmPKVAdRl4oeIaz0SUG/en2i/NpSYWQ93G2BtLw4SZ4+7TioAUGyhdCZvWeGrg== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:10:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:aa7:908c:0:b029:250:b584:a406 with SMTP id i12-20020aa7908c0000b0290250b584a406mr7014636pfa.44.1619825058460; Fri, 30 Apr 2021 16:24:18 -0700 (PDT) Date: Fri, 30 Apr 2021 16:24:07 -0700 In-Reply-To: <20210430232408.2707420-1-ricarkol@google.com> Message-Id: <20210430232408.2707420-6-ricarkol@google.com> Mime-Version: 1.0 References: <20210430232408.2707420-1-ricarkol@google.com> X-Mailer: git-send-email 2.31.1.527.g47e6f16901-goog Subject: [PATCH v2 5/5] KVM: selftests: Add aarch64/debug-exceptions test From: Ricardo Koller To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: pbonzini@redhat.com, maz@kernel.org, drjones@redhat.com, alexandru.elisei@arm.com, eric.auger@redhat.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Covers fundamental tests for debug exceptions. The guest installs and handle its debug exceptions itself, without KVM_SET_GUEST_DEBUG. Signed-off-by: Ricardo Koller Reviewed-by: Andrew Jones --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/aarch64/debug-exceptions.c | 244 ++++++++++++++++++ .../selftests/kvm/include/aarch64/processor.h | 14 +- 4 files changed, 254 insertions(+), 6 deletions(-) create mode 100644 tools/testing/selftests/kvm/aarch64/debug-exceptions.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index e65d5572aefc..f09ed908422b 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +/aarch64/debug-exceptions /aarch64/get-reg-list /aarch64/get-reg-list-sve /aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 618c5903f478..2f92442c0cc9 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -73,6 +73,7 @@ TEST_GEN_PROGS_x86_64 += memslot_modification_stress_test TEST_GEN_PROGS_x86_64 += set_memory_region_test TEST_GEN_PROGS_x86_64 += steal_time +TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list-sve TEST_GEN_PROGS_aarch64 += aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/aarch64/debug-exceptions.c b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c new file mode 100644 index 000000000000..87352ee09211 --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/debug-exceptions.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#define VCPU_ID 0 + +#define MDSCR_KDE (1 << 13) +#define MDSCR_MDE (1 << 15) +#define MDSCR_SS (1 << 0) + +#define DBGBCR_LEN8 (0xff << 5) +#define DBGBCR_EXEC (0x0 << 3) +#define DBGBCR_EL1 (0x1 << 1) +#define DBGBCR_E (0x1 << 0) + +#define DBGWCR_LEN8 (0xff << 5) +#define DBGWCR_RD (0x1 << 3) +#define DBGWCR_WR (0x2 << 3) +#define DBGWCR_EL1 (0x1 << 1) +#define DBGWCR_E (0x1 << 0) + +extern unsigned char sw_bp, hw_bp, bp_svc, bp_brk, hw_wp, ss_start; +static volatile uint64_t sw_bp_addr, hw_bp_addr; +static volatile uint64_t wp_addr, wp_data_addr; +static volatile uint64_t svc_addr; +static volatile uint64_t ss_addr[4], ss_idx; +#define PC(v) ((uint64_t)&(v)) + +static void reset_debug_state(void) +{ + asm volatile("msr daifset, #8"); + + write_sysreg(osdlr_el1, 0); + write_sysreg(oslar_el1, 0); + asm volatile("isb" : : : "memory"); + + write_sysreg(mdscr_el1, 0); + /* This test only uses the first bp and wp slot. */ + write_sysreg(dbgbvr0_el1, 0); + write_sysreg(dbgbcr0_el1, 0); + write_sysreg(dbgwcr0_el1, 0); + write_sysreg(dbgwvr0_el1, 0); + asm volatile("isb" : : : "memory"); +} + +static void install_wp(uint64_t addr) +{ + uint32_t wcr; + uint32_t mdscr; + + wcr = DBGWCR_LEN8 | DBGWCR_RD | DBGWCR_WR | DBGWCR_EL1 | DBGWCR_E; + write_sysreg(dbgwcr0_el1, wcr); + write_sysreg(dbgwvr0_el1, addr); + asm volatile("isb" : : : "memory"); + + asm volatile("msr daifclr, #8"); + + mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_MDE; + write_sysreg(mdscr_el1, mdscr); +} + +static void install_hw_bp(uint64_t addr) +{ + uint32_t bcr; + uint32_t mdscr; + + bcr = DBGBCR_LEN8 | DBGBCR_EXEC | DBGBCR_EL1 | DBGBCR_E; + write_sysreg(dbgbcr0_el1, bcr); + write_sysreg(dbgbvr0_el1, addr); + asm volatile("isb" : : : "memory"); + + asm volatile("msr daifclr, #8"); + + mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_MDE; + write_sysreg(mdscr_el1, mdscr); +} + +static void install_ss(void) +{ + uint32_t mdscr; + + asm volatile("msr daifclr, #8"); + + mdscr = read_sysreg(mdscr_el1) | MDSCR_KDE | MDSCR_SS; + write_sysreg(mdscr_el1, mdscr); +} + +static volatile char write_data; + +static void guest_code(void) +{ + GUEST_SYNC(0); + + /* Software-breakpoint */ + asm volatile("sw_bp: brk #0"); + GUEST_ASSERT_EQ(sw_bp_addr, PC(sw_bp)); + + GUEST_SYNC(1); + + /* Hardware-breakpoint */ + reset_debug_state(); + install_hw_bp(PC(hw_bp)); + asm volatile("hw_bp: nop"); + GUEST_ASSERT_EQ(hw_bp_addr, PC(hw_bp)); + + GUEST_SYNC(2); + + /* Hardware-breakpoint + svc */ + reset_debug_state(); + install_hw_bp(PC(bp_svc)); + asm volatile("bp_svc: svc #0"); + GUEST_ASSERT_EQ(hw_bp_addr, PC(bp_svc)); + GUEST_ASSERT_EQ(svc_addr, PC(bp_svc) + 4); + + GUEST_SYNC(3); + + /* Hardware-breakpoint + software-breakpoint */ + reset_debug_state(); + install_hw_bp(PC(bp_brk)); + asm volatile("bp_brk: brk #0"); + GUEST_ASSERT_EQ(sw_bp_addr, PC(bp_brk)); + GUEST_ASSERT_EQ(hw_bp_addr, PC(bp_brk)); + + GUEST_SYNC(4); + + /* Watchpoint */ + reset_debug_state(); + install_wp(PC(write_data)); + write_data = 'x'; + GUEST_ASSERT_EQ(write_data, 'x'); + GUEST_ASSERT_EQ(wp_data_addr, PC(write_data)); + + GUEST_SYNC(5); + + /* Single-step */ + reset_debug_state(); + install_ss(); + ss_idx = 0; + asm volatile("ss_start:\n" + "mrs x0, esr_el1\n" + "add x0, x0, #1\n" + "msr daifset, #8\n" + : : : "x0"); + GUEST_ASSERT_EQ(ss_addr[0], PC(ss_start)); + GUEST_ASSERT_EQ(ss_addr[1], PC(ss_start) + 4); + GUEST_ASSERT_EQ(ss_addr[2], PC(ss_start) + 8); + + GUEST_DONE(); +} + +static void guest_sw_bp_handler(struct ex_regs *regs) +{ + sw_bp_addr = regs->pc; + regs->pc += 4; +} + +static void guest_hw_bp_handler(struct ex_regs *regs) +{ + hw_bp_addr = regs->pc; + regs->pstate |= SPSR_D; +} + +static void guest_wp_handler(struct ex_regs *regs) +{ + wp_data_addr = read_sysreg(far_el1); + wp_addr = regs->pc; + regs->pstate |= SPSR_D; +} + +static void guest_ss_handler(struct ex_regs *regs) +{ + GUEST_ASSERT_1(ss_idx < 4, ss_idx); + ss_addr[ss_idx++] = regs->pc; + regs->pstate |= SPSR_SS; +} + +static void guest_svc_handler(struct ex_regs *regs) +{ + svc_addr = regs->pc; +} + +static int debug_version(struct kvm_vm *vm) +{ + uint64_t id_aa64dfr0; + + get_reg(vm, VCPU_ID, ARM64_SYS_REG(ID_AA64DFR0_EL1), &id_aa64dfr0); + return id_aa64dfr0 & 0xf; +} + +int main(int argc, char *argv[]) +{ + struct kvm_vm *vm; + struct ucall uc; + int stage; + + vm = vm_create_default(VCPU_ID, 0, guest_code); + ucall_init(vm, NULL); + + vm_init_descriptor_tables(vm); + vcpu_init_descriptor_tables(vm, VCPU_ID); + + if (debug_version(vm) < 6) { + print_skip("Armv8 debug architecture not supported."); + kvm_vm_free(vm); + exit(KSFT_SKIP); + } + + vm_install_exception_handler(vm, VECTOR_SYNC_CURRENT, + ESR_EC_BRK_INS, guest_sw_bp_handler); + vm_install_exception_handler(vm, VECTOR_SYNC_CURRENT, + ESR_EC_HW_BP_CURRENT, guest_hw_bp_handler); + vm_install_exception_handler(vm, VECTOR_SYNC_CURRENT, + ESR_EC_WP_CURRENT, guest_wp_handler); + vm_install_exception_handler(vm, VECTOR_SYNC_CURRENT, + ESR_EC_SSTEP_CURRENT, guest_ss_handler); + vm_install_exception_handler(vm, VECTOR_SYNC_CURRENT, + ESR_EC_SVC64, guest_svc_handler); + + for (stage = 0; stage < 7; stage++) { + vcpu_run(vm, VCPU_ID); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + TEST_ASSERT(uc.args[1] == stage, + "Stage %d: Unexpected sync ucall, got %lx", + stage, (ulong)uc.args[1]); + break; + case UCALL_ABORT: + TEST_FAIL("%s at %s:%ld\n\tvalues: %#lx, %#lx", + (const char *)uc.args[0], + __FILE__, uc.args[1], uc.args[2], uc.args[3]); + break; + case UCALL_DONE: + goto done; + default: + TEST_FAIL("Unknown ucall %lu", uc.cmd); + } + } + +done: + kvm_vm_free(vm); + return 0; +} diff --git a/tools/testing/selftests/kvm/include/aarch64/processor.h b/tools/testing/selftests/kvm/include/aarch64/processor.h index 40aae31b4afc..a3ebef8e88c7 100644 --- a/tools/testing/selftests/kvm/include/aarch64/processor.h +++ b/tools/testing/selftests/kvm/include/aarch64/processor.h @@ -14,12 +14,14 @@ #define ARM64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) -#define CPACR_EL1 3, 0, 1, 0, 2 -#define TCR_EL1 3, 0, 2, 0, 2 -#define MAIR_EL1 3, 0, 10, 2, 0 -#define TTBR0_EL1 3, 0, 2, 0, 0 -#define SCTLR_EL1 3, 0, 1, 0, 0 -#define VBAR_EL1 3, 0, 12, 0, 0 +#define CPACR_EL1 3, 0, 1, 0, 2 +#define TCR_EL1 3, 0, 2, 0, 2 +#define MAIR_EL1 3, 0, 10, 2, 0 +#define TTBR0_EL1 3, 0, 2, 0, 0 +#define SCTLR_EL1 3, 0, 1, 0, 0 +#define VBAR_EL1 3, 0, 12, 0, 0 + +#define ID_AA64DFR0_EL1 3, 0, 0, 5, 0 /* * Default MAIR