From patchwork Tue Nov 9 02:38:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609591 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47778C433F5 for ; Tue, 9 Nov 2021 02:39:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2E68E619E5 for ; Tue, 9 Nov 2021 02:39:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240656AbhKICmB (ORCPT ); Mon, 8 Nov 2021 21:42:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238491AbhKICmA (ORCPT ); Mon, 8 Nov 2021 21:42:00 -0500 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 3C7F3C061570 for ; Mon, 8 Nov 2021 18:39:15 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id s22-20020a056a0008d600b00480fea2e96cso11983987pfu.7 for ; Mon, 08 Nov 2021 18:39:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=0y7vLMxPPl6BScQAMjV8Fjo9DYu63xojaNRWz6NZJZ4=; b=DyUrPyS0UzVyIdnSnkJ03UWv3pnOgXolI/cmm/sQiHRzDs6JZCp41VErdDW2z1ZMNn Zevovaq4V3Qz6AeSv61OzBja4qAYo979y5f8PFcgtB4oexNXCco4EdEdSgxVSYd6/2af lyXWIe/+g2OJ/MPnnRGYliEsWaIuOfP8kznXzW531r3dmZJNs/DGTKMCOi8mQggNpxXC xT1CiEqv4VnXyM0AxjdK+kQE+/mBVP1Ocu4ifyfMVvoxFLstR0TGA91fB98+m+g8jxHy 2YfNaK2gFdNd75nKtNYMcr5o/iuzZ659mIly27tgxWuT7Rs/KEa7/CmPEq45pOdqSiV7 gXQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=0y7vLMxPPl6BScQAMjV8Fjo9DYu63xojaNRWz6NZJZ4=; b=WU0swJl2V84K3G+qLtZZLoQmKNMM13g+zmtREOi3nHjFg3tRGWKTwoEMeLGNJPrRXm kRfQMDvdyVPxWa+CsmO5uIKJ/9WDDIIy/z9/wk3c0D0L7b/ppigdV7G5DQ0La92HHT9a z6X+BPFducYbKvV1V3etW30cTJoUjuVuUlm6ASiRDyykjamHimSq2hcF0E8YAn68O/do yCRNyJi08juFScEw8EWczCo9HLDCw7Pyg5cfJpWTv605MVAR5NmZJebCNPIsuSbGHGAp 37HttOVMXsXgqMWtEQvG4JJC3hI0/yDDFPVaDLVfMzfvSvJcv/Pb+iIW42AgXCAm/cvB qN2w== X-Gm-Message-State: AOAM531qSI+SNDR/svuM1aSMnof1CevWn04m5kWsBY+0tFT7MahYMKcp JSGF2m0O9Bbi26SS86OMEo3DnJNjvBW0Ca+xHrfS0fFRDEi4qcXMZsZ7+0OVp8Zev0Vm2YvUFeG lUvVaE6Z/y+FEveLOWEYupMIfyCofKWrZunWFdesj8IdlnTkAjM5maiFkKshzspk= X-Google-Smtp-Source: ABdhPJxA15p+zaxKKjY4+9kinUUQXs0xiR2NDdQyVjcdaW+yoPUj15VMTcoiMYFRVxMo0xcpqR82q2PaCEXchg== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:b7cb:b0:141:b33a:9589 with SMTP id v11-20020a170902b7cb00b00141b33a9589mr3618554plz.9.1636425554628; Mon, 08 Nov 2021 18:39:14 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:50 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-2-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 01/17] KVM: selftests: aarch64: move gic_v3.h to shared headers From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move gic_v3.h to the shared headers location. There are some definitions that will be used in the vgic-irq test. Signed-off-by: Ricardo Koller --- tools/testing/selftests/kvm/{lib => include}/aarch64/gic_v3.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tools/testing/selftests/kvm/{lib => include}/aarch64/gic_v3.h (100%) diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.h b/tools/testing/selftests/kvm/include/aarch64/gic_v3.h similarity index 100% rename from tools/testing/selftests/kvm/lib/aarch64/gic_v3.h rename to tools/testing/selftests/kvm/include/aarch64/gic_v3.h From patchwork Tue Nov 9 02:38:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609593 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32BC3C433EF for ; Tue, 9 Nov 2021 02:39:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 173B0619BB for ; Tue, 9 Nov 2021 02:39:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241294AbhKICmD (ORCPT ); Mon, 8 Nov 2021 21:42:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238491AbhKICmB (ORCPT ); Mon, 8 Nov 2021 21:42:01 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88A09C061570 for ; Mon, 8 Nov 2021 18:39:16 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id r11-20020a170902be0b00b0013f4f30d71cso7656624pls.21 for ; Mon, 08 Nov 2021 18:39:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=loxMeAeqhpiKSvyXoOE21nDz6NxFuQUOOaGjcUtPr9Y=; b=MPBHIzvwhMn3f4yNpS714cQcUrKXhSzFKQhJJsxLnKNQ270GW+osyzjO9GvjzIpyiD 1k0VBUDy5gEAe3BwH7vYKZniPHXtHs+f/a0jCvHUhVjKAiP177Xu5skV1xi3ytJ/uN8X u6bYt4Rlu2bZdGlg96xUNOoV2Y8TRV9XyavcoV4jmXmxVX36aXl4qYBWpn2myOO1AyuN kRxAJ3Gmdw9vMQhilsQlfH4ZYhBkMILM0tzSqgcQQpDkvXom+HrTVCRKYGIuZBLDMyhV V6ylEC7dCxpE3ShHS0oQyddi7Xnswq2xD1iSxLiCNJY7G5zBYQ13b9tztn6kzb6vQ5i4 pdFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=loxMeAeqhpiKSvyXoOE21nDz6NxFuQUOOaGjcUtPr9Y=; b=nuxXedcw4OkX5CJANCBLqrycrC4nwJYXBLuGcj9gj7A1R/ymj9XD7Q1oXotBVBPRo1 MCYsHKs2miCWmBoSoV9nN6kw2Ezxmense7yllw5Zj067y57ll8K6qgv/D8ezXRutns4l oVkNefsE1HKnIm6C9XksgD/Mg62e5eECZjmFPBa/Tmbo4KsUwNUIn+3MUZRILcyZdvU3 f/3XmC2DdFXwIJ+4Iqwllzwqq/Hx6OpS92R+akNXnGEkyBs+bXNg2AvnbNw+7eYu4yBD nXdI65uJub50rMU2ZJDRss6re1sgxcCCAkT9jW+mpS5W+LQ05rQ0npuQ+qHoI2Tx47/F q5ug== X-Gm-Message-State: AOAM533/0Gq2A6OkxXwbuZe1dGlpLa45wTynuZHIfBcGag16vXBu8OI5 +mxR32FUZsZGX0uaSGbjmQSR4Xa0gnsbRNI0N/Skr+PABk9JCD3bAOHDX0C56IAn0sxcrSe+hbi 1vTbeKBaVqXhUPlFuNydjVvZlJs1b9JIS5jCvy2cf6vnWqKAItJ6JblHFe7Kz01Y= X-Google-Smtp-Source: ABdhPJx4by6npC6Bw0eZYMhu8Sm094t2D7pgKDmPKyanQSa9LkHub+gt4LWj8jhp7QyGQhSy5iSsdpoTBcdQ8w== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:aa7:9197:0:b0:44d:a2e9:72cf with SMTP id x23-20020aa79197000000b0044da2e972cfmr4519442pfa.38.1636425555973; Mon, 08 Nov 2021 18:39:15 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:51 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-3-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 02/17] KVM: selftests: aarch64: add function for accessing GICv3 dist and redist registers From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a generic library function for reading and writing GICv3 distributor and redistributor registers. Then adapt some functions to use it; more will come and use it in the next commit. Signed-off-by: Ricardo Koller --- .../selftests/kvm/lib/aarch64/gic_v3.c | 124 ++++++++++++++---- 1 file changed, 101 insertions(+), 23 deletions(-) diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c index 2dbf3339b62e..00e944fd8148 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c @@ -19,7 +19,8 @@ struct gicv3_data { unsigned int nr_spis; }; -#define sgi_base_from_redist(redist_base) (redist_base + SZ_64K) +#define sgi_base_from_redist(redist_base) (redist_base + SZ_64K) +#define DIST_BIT (1U << 31) enum gicv3_intid_range { SGI_RANGE, @@ -50,6 +51,14 @@ static void gicv3_gicr_wait_for_rwp(void *redist_base) } } +static void gicv3_wait_for_rwp(uint32_t cpu_or_dist) +{ + if (cpu_or_dist & DIST_BIT) + gicv3_gicd_wait_for_rwp(); + else + gicv3_gicr_wait_for_rwp(gicv3_data.redist_base[cpu_or_dist]); +} + static enum gicv3_intid_range get_intid_range(unsigned int intid) { switch (intid) { @@ -81,39 +90,108 @@ static void gicv3_write_eoir(uint32_t irq) isb(); } -static void -gicv3_config_irq(unsigned int intid, unsigned int offset) +uint32_t gicv3_reg_readl(uint32_t cpu_or_dist, uint64_t offset) +{ + void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base + : sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]); + return readl(base + offset); +} + +void gicv3_reg_writel(uint32_t cpu_or_dist, uint64_t offset, uint32_t reg_val) +{ + void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base + : sgi_base_from_redist(gicv3_data.redist_base[cpu_or_dist]); + writel(reg_val, base + offset); +} + +uint32_t gicv3_getl_fields(uint32_t cpu_or_dist, uint64_t offset, uint32_t mask) +{ + return gicv3_reg_readl(cpu_or_dist, offset) & mask; +} + +void gicv3_setl_fields(uint32_t cpu_or_dist, uint64_t offset, + uint32_t mask, uint32_t reg_val) +{ + uint32_t tmp = gicv3_reg_readl(cpu_or_dist, offset) & ~mask; + + tmp |= (reg_val & mask); + gicv3_reg_writel(cpu_or_dist, offset, tmp); +} + +/* + * We use a single offset for the distributor and redistributor maps as they + * have the same value in both. The only exceptions are registers that only + * exist in one and not the other, like GICR_WAKER that doesn't exist in the + * distributor map. Such registers are conveniently marked as reserved in the + * map that doesn't implement it; like GICR_WAKER's offset of 0x0014 being + * marked as "Reserved" in the Distributor map. + */ +static void gicv3_access_reg(uint32_t intid, uint64_t offset, + uint32_t reg_bits, uint32_t bits_per_field, + bool write, uint32_t *val) { uint32_t cpu = guest_get_vcpuid(); - uint32_t mask = 1 << (intid % 32); enum gicv3_intid_range intid_range = get_intid_range(intid); - void *reg; - - /* We care about 'cpu' only for SGIs or PPIs */ - if (intid_range == SGI_RANGE || intid_range == PPI_RANGE) { - GUEST_ASSERT(cpu < gicv3_data.nr_cpus); - - reg = sgi_base_from_redist(gicv3_data.redist_base[cpu]) + - offset; - writel(mask, reg); - gicv3_gicr_wait_for_rwp(gicv3_data.redist_base[cpu]); - } else if (intid_range == SPI_RANGE) { - reg = gicv3_data.dist_base + offset + (intid / 32) * 4; - writel(mask, reg); - gicv3_gicd_wait_for_rwp(); - } else { - GUEST_ASSERT(0); - } + uint32_t fields_per_reg, index, mask, shift; + uint32_t cpu_or_dist; + + GUEST_ASSERT(bits_per_field <= reg_bits); + GUEST_ASSERT(*val < (1U << bits_per_field)); + /* Some registers like IROUTER are 64 bit long. Those are currently not + * supported by readl nor writel, so just asserting here until then. + */ + GUEST_ASSERT(reg_bits == 32); + + fields_per_reg = reg_bits / bits_per_field; + index = intid % fields_per_reg; + shift = index * bits_per_field; + mask = ((1U << bits_per_field) - 1) << shift; + + /* Set offset to the actual register holding intid's config. */ + offset += (intid / fields_per_reg) * (reg_bits / 8); + + cpu_or_dist = (intid_range == SPI_RANGE) ? DIST_BIT : cpu; + + if (write) + gicv3_setl_fields(cpu_or_dist, offset, mask, *val << shift); + *val = gicv3_getl_fields(cpu_or_dist, offset, mask) >> shift; +} + +static void gicv3_write_reg(uint32_t intid, uint64_t offset, + uint32_t reg_bits, uint32_t bits_per_field, uint32_t val) +{ + gicv3_access_reg(intid, offset, reg_bits, + bits_per_field, true, &val); +} + +static uint32_t gicv3_read_reg(uint32_t intid, uint64_t offset, + uint32_t reg_bits, uint32_t bits_per_field) +{ + uint32_t val; + + gicv3_access_reg(intid, offset, reg_bits, + bits_per_field, false, &val); + return val; } static void gicv3_irq_enable(unsigned int intid) { - gicv3_config_irq(intid, GICD_ISENABLER); + bool is_spi = get_intid_range(intid) == SPI_RANGE; + unsigned int val = 1; + uint32_t cpu = guest_get_vcpuid(); + + gicv3_write_reg(intid, GICD_ISENABLER, 32, 1, val); + gicv3_wait_for_rwp(is_spi ? DIST_BIT : cpu); } static void gicv3_irq_disable(unsigned int intid) { - gicv3_config_irq(intid, GICD_ICENABLER); + bool is_spi = get_intid_range(intid) == SPI_RANGE; + uint32_t val = 1; + uint32_t cpu = guest_get_vcpuid(); + + gicv3_write_reg(intid, GICD_ICENABLER, 32, 1, val); + gicv3_wait_for_rwp(is_spi ? DIST_BIT : cpu); } static void gicv3_enable_redist(void *redist_base) From patchwork Tue Nov 9 02:38:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609595 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33A01C433FE for ; Tue, 9 Nov 2021 02:39:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 166E2619EC for ; Tue, 9 Nov 2021 02:39:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241425AbhKICmE (ORCPT ); Mon, 8 Nov 2021 21:42:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37872 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238491AbhKICmD (ORCPT ); Mon, 8 Nov 2021 21:42:03 -0500 Received: from mail-qv1-xf4a.google.com (mail-qv1-xf4a.google.com [IPv6:2607:f8b0:4864:20::f4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2240C061570 for ; Mon, 8 Nov 2021 18:39:18 -0800 (PST) Received: by mail-qv1-xf4a.google.com with SMTP id q9-20020ad45749000000b003bdeb0612c5so10616298qvx.8 for ; Mon, 08 Nov 2021 18:39:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=hAgPV3xFyyvPsO0tGe3b/FMKmByO5nfhAdx996Q4woA=; b=J1wu4iwXjHJfHIDEyBesp37qGjNRGqslkAdb3lWsA1VUH4QWX6ioijCBorRe8lsaD5 KgYuQ8vO8gFdVEYZ4ti/biaEBy+zhkaf/TrlPDtlqBIudlmQjS7NQ2cxj6n4TEhjc7tp xi74xZD4sgSQvvNZHZ9wMEqZLSQQI7gzRor1azpzQzMXCsHDklG6A0X6a9E/uSm/a1De /cnwgOkzJ1gugbSuXcnvkIRHN88cQEl5sQJ9IgvCl9MpEI3EsBumZtKPAZWwfOW/u13j pwXAXzG6hDmpudh7+Cq0NNXq4YIKg5s8/Z7WoHotpTP0At9FnC1kRmZsB451jgytjuP2 mWnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hAgPV3xFyyvPsO0tGe3b/FMKmByO5nfhAdx996Q4woA=; b=VmlkmEXVSQHflQLGNhItJyIVZzddXxNqAHojWVVNJUgMPmStH7ORk748oKr+GnDsxD wnQ0Aywr0gr+jO7IqkVUs8POoNJa4txpFUNJwk2v1Kvbvjko8RvxZxQgcIB5O8f6P3qV 6KUN2nEpyVyYB3bS6rcrlQvLIj4gYf8/cak6CMCm/TtGyHgx48pyicCz2zBcTcIAE340 c4D4LWLBojTY4ZFbca9bQ9xLq/HsGvsxm1HQxnf6h27Q5lcdDGvjnd6YL85NPM7a5Y4s SayNw3qhFrEIoBK+On2FhxEzaX0jlu7UqwuhIe5mFqCt2rNJYJY1Ls3QHSY2xe5S1HHM I4gw== X-Gm-Message-State: AOAM530LGs/VCwZybMCI81I9BbrvoQFe+RtHI6SXWQHEsGH32RB3sLe9 zCGDMU+bNXI99BzQuaS4AvsoAHRumWOC2XPpsTSuC+FMK59IVOhXM23JWWnEiCnHnk22KLWBu8Y l30hcf+JI/O2zDhGRIVvLcuv1/Wlx1EqEv7I+fIW1R1q5Kl2M2MzymEXFFealhts= X-Google-Smtp-Source: ABdhPJzshOLNQDU11XH2FvYs2Wq6hLMDiKnHEcAtWCt1tloFz/p13cI0EDFuEO562W0HLuOwPCVqDUFw0N2oWw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:ac8:58c5:: with SMTP id u5mr4665298qta.199.1636425557761; Mon, 08 Nov 2021 18:39:17 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:52 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-4-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 03/17] KVM: selftests: aarch64: add GICv3 register accessor library functions From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add library functions for accessing GICv3 registers: DIR, PMR, CTLR, ISACTIVER, ISPENDR. Signed-off-by: Ricardo Koller --- .../selftests/kvm/include/aarch64/gic.h | 16 ++++ .../selftests/kvm/include/aarch64/gic_v3.h | 12 +++ tools/testing/selftests/kvm/lib/aarch64/gic.c | 66 ++++++++++++++ .../selftests/kvm/lib/aarch64/gic_private.h | 11 +++ .../selftests/kvm/lib/aarch64/gic_v3.c | 90 +++++++++++++++++-- 5 files changed, 189 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/include/aarch64/gic.h b/tools/testing/selftests/kvm/include/aarch64/gic.h index 85dd1e53048e..c932cf3d0771 100644 --- a/tools/testing/selftests/kvm/include/aarch64/gic.h +++ b/tools/testing/selftests/kvm/include/aarch64/gic.h @@ -17,5 +17,21 @@ void gic_irq_enable(unsigned int intid); void gic_irq_disable(unsigned int intid); unsigned int gic_get_and_ack_irq(void); void gic_set_eoi(unsigned int intid); +void gic_set_dir(unsigned int intid); + +/* + * Sets the EOI mode. When split is false, EOI just drops the priority. When + * split is true, EOI drops the priority and deactivates the interrupt. + */ +void gic_set_eoi_split(bool split); +void gic_set_priority_mask(uint64_t mask); +void gic_set_priority(uint32_t intid, uint32_t prio); +void gic_irq_set_active(unsigned int intid); +void gic_irq_clear_active(unsigned int intid); +bool gic_irq_get_active(unsigned int intid); +void gic_irq_set_pending(unsigned int intid); +void gic_irq_clear_pending(unsigned int intid); +bool gic_irq_get_pending(unsigned int intid); +void gic_irq_set_config(unsigned int intid, bool is_edge); #endif /* SELFTEST_KVM_GIC_H */ diff --git a/tools/testing/selftests/kvm/include/aarch64/gic_v3.h b/tools/testing/selftests/kvm/include/aarch64/gic_v3.h index b51536d469a6..ba0886e8a2bb 100644 --- a/tools/testing/selftests/kvm/include/aarch64/gic_v3.h +++ b/tools/testing/selftests/kvm/include/aarch64/gic_v3.h @@ -16,8 +16,12 @@ #define GICD_IGROUPR 0x0080 #define GICD_ISENABLER 0x0100 #define GICD_ICENABLER 0x0180 +#define GICD_ISPENDR 0x0200 +#define GICD_ICPENDR 0x0280 #define GICD_ICACTIVER 0x0380 +#define GICD_ISACTIVER 0x0300 #define GICD_IPRIORITYR 0x0400 +#define GICD_ICFGR 0x0C00 /* * The assumption is that the guest runs in a non-secure mode. @@ -49,16 +53,24 @@ #define GICR_IGROUPR0 GICD_IGROUPR #define GICR_ISENABLER0 GICD_ISENABLER #define GICR_ICENABLER0 GICD_ICENABLER +#define GICR_ISPENDR0 GICD_ISPENDR +#define GICR_ISACTIVER0 GICD_ISACTIVER #define GICR_ICACTIVER0 GICD_ICACTIVER +#define GICR_ICENABLER GICD_ICENABLER +#define GICR_ICACTIVER GICD_ICACTIVER #define GICR_IPRIORITYR0 GICD_IPRIORITYR /* CPU interface registers */ #define SYS_ICC_PMR_EL1 sys_reg(3, 0, 4, 6, 0) #define SYS_ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0) #define SYS_ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1) +#define SYS_ICC_DIR_EL1 sys_reg(3, 0, 12, 11, 1) +#define SYS_ICC_CTLR_EL1 sys_reg(3, 0, 12, 12, 4) #define SYS_ICC_SRE_EL1 sys_reg(3, 0, 12, 12, 5) #define SYS_ICC_GRPEN1_EL1 sys_reg(3, 0, 12, 12, 7) +#define SYS_ICV_AP1R0_EL1 sys_reg(3, 0, 12, 9, 0) + #define ICC_PMR_DEF_PRIO 0xf0 #define ICC_SRE_EL1_SRE (1U << 0) diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic.c b/tools/testing/selftests/kvm/lib/aarch64/gic.c index fff4fc27504d..55668631d546 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/gic.c +++ b/tools/testing/selftests/kvm/lib/aarch64/gic.c @@ -93,3 +93,69 @@ void gic_set_eoi(unsigned int intid) GUEST_ASSERT(gic_common_ops); gic_common_ops->gic_write_eoir(intid); } + +void gic_set_dir(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_write_dir(intid); +} + +void gic_set_eoi_split(bool split) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_set_eoi_split(split); +} + +void gic_set_priority_mask(uint64_t pmr) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_set_priority_mask(pmr); +} + +void gic_set_priority(unsigned int intid, unsigned int prio) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_set_priority(intid, prio); +} + +void gic_irq_set_active(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_set_active(intid); +} + +void gic_irq_clear_active(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_clear_active(intid); +} + +bool gic_irq_get_active(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + return gic_common_ops->gic_irq_get_active(intid); +} + +void gic_irq_set_pending(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_set_pending(intid); +} + +void gic_irq_clear_pending(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_clear_pending(intid); +} + +bool gic_irq_get_pending(unsigned int intid) +{ + GUEST_ASSERT(gic_common_ops); + return gic_common_ops->gic_irq_get_pending(intid); +} + +void gic_irq_set_config(unsigned int intid, bool is_edge) +{ + GUEST_ASSERT(gic_common_ops); + gic_common_ops->gic_irq_set_config(intid, is_edge); +} diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_private.h b/tools/testing/selftests/kvm/lib/aarch64/gic_private.h index d81d739433dc..75d07313c893 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/gic_private.h +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_private.h @@ -14,6 +14,17 @@ struct gic_common_ops { void (*gic_irq_disable)(unsigned int intid); uint64_t (*gic_read_iar)(void); void (*gic_write_eoir)(uint32_t irq); + void (*gic_write_dir)(uint32_t irq); + void (*gic_set_eoi_split)(bool split); + void (*gic_set_priority_mask)(uint64_t mask); + void (*gic_set_priority)(uint32_t intid, uint32_t prio); + void (*gic_irq_set_active)(uint32_t intid); + void (*gic_irq_clear_active)(uint32_t intid); + bool (*gic_irq_get_active)(uint32_t intid); + void (*gic_irq_set_pending)(uint32_t intid); + void (*gic_irq_clear_pending)(uint32_t intid); + bool (*gic_irq_get_pending)(uint32_t intid); + void (*gic_irq_set_config)(uint32_t intid, bool is_edge); }; extern const struct gic_common_ops gicv3_ops; diff --git a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c index 00e944fd8148..00f613c0583c 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c +++ b/tools/testing/selftests/kvm/lib/aarch64/gic_v3.c @@ -90,6 +90,29 @@ static void gicv3_write_eoir(uint32_t irq) isb(); } +static void gicv3_write_dir(uint32_t irq) +{ + write_sysreg_s(irq, SYS_ICC_DIR_EL1); + isb(); +} + +static void gicv3_set_priority_mask(uint64_t mask) +{ + write_sysreg_s(mask, SYS_ICC_PMR_EL1); +} + +static void gicv3_set_eoi_split(bool split) +{ + uint32_t val; + + /* All other fields are read-only, so no need to read CTLR first. In + * fact, the kernel does the same. + */ + val = split ? (1U << 1) : 0; + write_sysreg_s(val, SYS_ICC_CTLR_EL1); + isb(); +} + uint32_t gicv3_reg_readl(uint32_t cpu_or_dist, uint64_t offset) { void *base = cpu_or_dist & DIST_BIT ? gicv3_data.dist_base @@ -174,26 +197,70 @@ static uint32_t gicv3_read_reg(uint32_t intid, uint64_t offset, return val; } -static void gicv3_irq_enable(unsigned int intid) +static void gicv3_set_priority(uint32_t intid, uint32_t prio) +{ + gicv3_write_reg(intid, GICD_IPRIORITYR, 32, 8, prio); +} + +/* Sets the intid to be level-sensitive or edge-triggered. */ +static void gicv3_irq_set_config(uint32_t intid, bool is_edge) +{ + uint32_t val; + + /* N/A for private interrupts. */ + GUEST_ASSERT(get_intid_range(intid) == SPI_RANGE); + val = is_edge ? 2 : 0; + gicv3_write_reg(intid, GICD_ICFGR, 32, 2, val); +} + +static void gicv3_irq_enable(uint32_t intid) { bool is_spi = get_intid_range(intid) == SPI_RANGE; - unsigned int val = 1; uint32_t cpu = guest_get_vcpuid(); - gicv3_write_reg(intid, GICD_ISENABLER, 32, 1, val); + gicv3_write_reg(intid, GICD_ISENABLER, 32, 1, 1); gicv3_wait_for_rwp(is_spi ? DIST_BIT : cpu); } -static void gicv3_irq_disable(unsigned int intid) +static void gicv3_irq_disable(uint32_t intid) { bool is_spi = get_intid_range(intid) == SPI_RANGE; - uint32_t val = 1; uint32_t cpu = guest_get_vcpuid(); - gicv3_write_reg(intid, GICD_ICENABLER, 32, 1, val); + gicv3_write_reg(intid, GICD_ICENABLER, 32, 1, 1); gicv3_wait_for_rwp(is_spi ? DIST_BIT : cpu); } +static void gicv3_irq_set_active(uint32_t intid) +{ + gicv3_write_reg(intid, GICD_ISACTIVER, 32, 1, 1); +} + +static void gicv3_irq_clear_active(uint32_t intid) +{ + gicv3_write_reg(intid, GICD_ICACTIVER, 32, 1, 1); +} + +static bool gicv3_irq_get_active(uint32_t intid) +{ + return gicv3_read_reg(intid, GICD_ISACTIVER, 32, 1); +} + +static void gicv3_irq_set_pending(uint32_t intid) +{ + gicv3_write_reg(intid, GICD_ISPENDR, 32, 1, 1); +} + +static void gicv3_irq_clear_pending(uint32_t intid) +{ + gicv3_write_reg(intid, GICD_ICPENDR, 32, 1, 1); +} + +static bool gicv3_irq_get_pending(uint32_t intid) +{ + return gicv3_read_reg(intid, GICD_ISPENDR, 32, 1); +} + static void gicv3_enable_redist(void *redist_base) { uint32_t val = readl(redist_base + GICR_WAKER); @@ -315,4 +382,15 @@ const struct gic_common_ops gicv3_ops = { .gic_irq_disable = gicv3_irq_disable, .gic_read_iar = gicv3_read_iar, .gic_write_eoir = gicv3_write_eoir, + .gic_write_dir = gicv3_write_dir, + .gic_set_priority_mask = gicv3_set_priority_mask, + .gic_set_eoi_split = gicv3_set_eoi_split, + .gic_set_priority = gicv3_set_priority, + .gic_irq_set_active = gicv3_irq_set_active, + .gic_irq_clear_active = gicv3_irq_clear_active, + .gic_irq_get_active = gicv3_irq_get_active, + .gic_irq_set_pending = gicv3_irq_set_pending, + .gic_irq_clear_pending = gicv3_irq_clear_pending, + .gic_irq_get_pending = gicv3_irq_get_pending, + .gic_irq_set_config = gicv3_irq_set_config, }; From patchwork Tue Nov 9 02:38:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609597 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D323FC433F5 for ; Tue, 9 Nov 2021 02:39:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B931D619F5 for ; Tue, 9 Nov 2021 02:39:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238491AbhKICmG (ORCPT ); Mon, 8 Nov 2021 21:42:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241508AbhKICmF (ORCPT ); Mon, 8 Nov 2021 21:42:05 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFD8CC061570 for ; Mon, 8 Nov 2021 18:39:19 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id w4-20020a1709029a8400b00138e222b06aso7685937plp.12 for ; Mon, 08 Nov 2021 18:39:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=uniPEnuX0gk6QJKFukwf5b6AeT8wkhedLb4e6yWrmRE=; b=cG46+tLyMfC8E+1FJHQpqSu4Vbj+OiIbfEpy5p1NQAa+m49AfuMrjXaxrgO6GHL0aY TeOOBhzqqxWrm8iHjdug9No4pC+oTadJGj+iziMUuNt2Myh2dR0jb/Eykriurjpu4lBk 9kdjPokVXRh/shl9/6okG7g3U4+pd1ukU09oNuQB6vFrB00cQXNzuYMQ60yTL46wa0co +BPaT52cPC1eD4cQBBvE+UT2U36X+J6uBTYEONmYRYtRKQ3GGlJZ48KlVjurtTPg0yNb K77of8S0UO8HCuEur5bB2c90AaHve/TCp/NZMuDjeIawRFQAGKBhlE2ImpiMnv0gDG2U fcoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=uniPEnuX0gk6QJKFukwf5b6AeT8wkhedLb4e6yWrmRE=; b=7/YiAcFIFhFDHTFFN3V+jMSJ+3wMwqWqUnSk1tBu+zBUxaMR5uODSxz2yJSuGOMog5 qH7jGoQxQuwlvcOmv4i8BFsk+zbOwWBKjrWNd6c/S5PBzpF2VSVGOqetG7YuQL9i7uno twiTMBYidHTzsAiGXPrKD96ycP8XuKFyKwqx1X5Y81YBcBNK6T+h3zBPvoVDFCT135fh IgrESvPhiE5z2H5v/0aiMfxWvX4zjtwy19jA7DWKDhL1+87kL4gXY2QORjO5dSZRlknd WosRSaqsYj2dEaqAGZzKReYS6FEJ6ITUdrtb666A/4CC6n+vX6TSHPPlPw8ruZCw4lJX bEpg== X-Gm-Message-State: AOAM532p3SYL3VKfOud/NxaFv8HErspeahXv7I90Om74hWz1BvXncep7 y0XYwRHuTl+NvYy15Q8AotvH6uzCupjrGiE125gBGQun2kzIhYLcZuIR2f4jWTCwR54syHtyUEC cmkTY+Z/P12OkD+2FLov/pIJIUUBPX0LAy2gcHznxfFfcaAi8WB3XFw4NZYFgY9I= X-Google-Smtp-Source: ABdhPJzM2HDlpLCFeVGD1I8VKS6/Hls1yIJys+w+uzA32rZ+hWXRKhQTWiwEtpYWa+gIZZ+AndDlQYxnlSUrKw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90b:4ad0:: with SMTP id mh16mr3376599pjb.176.1636425559349; Mon, 08 Nov 2021 18:39:19 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:53 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-5-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 04/17] KVM: selftests: add kvm_irq_line library function From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add an architecture independent wrapper function for the KVM_IRQ_LINE ioctl. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/include/kvm_util.h | 2 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index f6b3794f306b..c6831fd8aea7 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -239,6 +239,8 @@ int _kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, void *val, bool write); int kvm_device_access(int dev_fd, uint32_t group, uint64_t attr, void *val, bool write); +void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); +int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level); int _vcpu_has_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, uint64_t attr); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 041004c0fda7..7d9cb8358702 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2078,6 +2078,27 @@ int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, return ret; } +/* + * IRQ related functions. + */ + +int _kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level) +{ + struct kvm_irq_level irq_level = { + .irq = irq, + .level = level, + }; + + return _vm_ioctl(vm, KVM_IRQ_LINE, &irq_level); +} + +void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level) +{ + int ret = _kvm_irq_line(vm, irq, level); + + TEST_ASSERT(ret >= 0, "KVM_IRQ_LINE failed, rc: %i errno: %i", ret, errno); +} + /* * VM Dump * From patchwork Tue Nov 9 02:38:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609599 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5004C433F5 for ; Tue, 9 Nov 2021 02:39:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8CE5E619E8 for ; Tue, 9 Nov 2021 02:39:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241508AbhKICmH (ORCPT ); Mon, 8 Nov 2021 21:42:07 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241574AbhKICmG (ORCPT ); Mon, 8 Nov 2021 21:42:06 -0500 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 861AAC061767 for ; Mon, 8 Nov 2021 18:39:21 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id x9-20020a056a00188900b0049fd22b9a27so3086710pfh.18 for ; Mon, 08 Nov 2021 18:39:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=V23efQreReel1ozFxcUFhqnQ3/YomiRoI5LYnXWRjFY=; b=HYJuwjh9Xre4+MctGxwHLrNFFy3cG3Ulns760IlOKUiCA76HVa1D/YIkjdXF7+YaVd 5MJ0FCXO+JtGKgOdRKNmkvsPGVWo7JQxBqqg2CSAVwXfGBcizbazagrUMEnc6hDgqYnl uuIkPUGjDRsXf22bYDVYxvpNLCzt/6QFkpm+gSxNAQiIP9A13R7XY+SOAaWbN88iK7Us ALwJ3zCClW4iLiML+y/9+nZAeLtWxx/zWbhnnrljA2GZPRU59/E20ZwCKOjRH7Pkg+si 5BRRm+VHesV4E5YDVp2vUljUMrhMCvQGNyTH3BFGpHPxVQCFIQbFsT8N3tuYD/dgWohQ Xl0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=V23efQreReel1ozFxcUFhqnQ3/YomiRoI5LYnXWRjFY=; b=JHhphV/+SHfO3ZOZoiYUZE+kq016dIxCK5a3pfaoOgaYur2p3DFMU+jG3h48pUJT1o 6d2bsLaMdMJ2k7Gfb7dXl4gg3Hxrm0Nc81RYRA41IcPjszQyRauljvGUXm9/gEtetgn3 xKRe6AX494WaZfA74KXET2WcSAbyuFI0YuQYoWEtrUIM3Y5iY1/bV0RFvCRpHEWRUwzS o1VsBXbhSJE6b1HQSYkBIsAqbd3j+XPRrPgNpJQrX98jMYdHlfsKlWh/bQCZVzSwVXfF OOZvreBOLBKdcfO70xGFePXYB4MvpFfdVjTfj1KJE4K0Geoqe+MYQ/syKEKgk1EUuP4c 1gYw== X-Gm-Message-State: AOAM532zpZdaPwwNosOzLHT966plN7aDWTP7iFCA9JuVP7Lrr4FgiY3Q y2x8rr316Z7YtqOdJaA9VmdMRFaSTZgiKmRUXTvMOq85hvloqDdI8Rwjcz12xmOpEN7uof9Oav7 M+YeKUsOgqkudul6hi4/hmzBkJbdzZA4l9K0rv1ngfXPqYxAL47WK0HbpznwXh/I= X-Google-Smtp-Source: ABdhPJwCFndNR00w3y5o+Z3mzR0MnzC15TZzdbkvYri6oPSzB1KiV8KnaSY6nZpga7EMDygy9OHbOX7MNsnyug== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:e74a:b0:142:114c:1f1e with SMTP id p10-20020a170902e74a00b00142114c1f1emr4013166plf.78.1636425560906; Mon, 08 Nov 2021 18:39:20 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:54 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-6-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 05/17] KVM: selftests: aarch64: add vGIC library functions to deal with vIRQ state From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a set of library functions for userspace code in selftests to deal with vIRQ state (i.e., ioctl wrappers). Signed-off-by: Ricardo Koller --- .../selftests/kvm/include/aarch64/gic.h | 10 ++ .../selftests/kvm/include/aarch64/vgic.h | 14 ++- .../testing/selftests/kvm/lib/aarch64/vgic.c | 93 +++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/include/aarch64/gic.h b/tools/testing/selftests/kvm/include/aarch64/gic.h index c932cf3d0771..b217ea17cac5 100644 --- a/tools/testing/selftests/kvm/include/aarch64/gic.h +++ b/tools/testing/selftests/kvm/include/aarch64/gic.h @@ -11,6 +11,16 @@ enum gic_type { GIC_TYPE_MAX, }; +#define MIN_SGI 0 +#define MIN_PPI 16 +#define MIN_SPI 32 +#define MAX_SPI 1019 +#define IAR_SPURIOUS 1023 + +#define INTID_IS_SGI(intid) (0 <= (intid) && (intid) < MIN_PPI) +#define INTID_IS_PPI(intid) (MIN_PPI <= (intid) && (intid) < MIN_SPI) +#define INTID_IS_SPI(intid) (MIN_SPI <= (intid) && (intid) <= MAX_SPI) + void gic_init(enum gic_type type, unsigned int nr_cpus, void *dist_base, void *redist_base); void gic_irq_enable(unsigned int intid); diff --git a/tools/testing/selftests/kvm/include/aarch64/vgic.h b/tools/testing/selftests/kvm/include/aarch64/vgic.h index 0ecfb253893c..ec8744bb2d4b 100644 --- a/tools/testing/selftests/kvm/include/aarch64/vgic.h +++ b/tools/testing/selftests/kvm/include/aarch64/vgic.h @@ -17,4 +17,16 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint64_t gicd_base_gpa, uint64_t gicr_base_gpa); -#endif /* SELFTEST_KVM_VGIC_H */ +#define VGIC_MAX_RESERVED 1023 + +void kvm_irq_set_level_info(int gic_fd, uint32_t intid, int level); +int _kvm_irq_set_level_info(int gic_fd, uint32_t intid, int level); + +void kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level); +int _kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level); + +/* The vcpu arg only applies to private interrupts. */ +void kvm_irq_write_ispendr(int gic_fd, uint32_t intid, uint32_t vcpu); +void kvm_irq_write_isactiver(int gic_fd, uint32_t intid, uint32_t vcpu); + +#endif // SELFTEST_KVM_VGIC_H diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c index b9b271ff520d..a1f1f6c8e2e0 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c @@ -5,11 +5,14 @@ #include #include +#include #include #include "kvm_util.h" #include "../kvm_util_internal.h" #include "vgic.h" +#include "gic.h" +#include "gic_v3.h" /* * vGIC-v3 default host setup @@ -68,3 +71,93 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, return gic_fd; } + +/* should only work for level sensitive interrupts */ +int _kvm_irq_set_level_info(int gic_fd, uint32_t intid, int level) +{ + uint64_t attr = 32 * (intid / 32); + uint64_t index = intid % 32; + uint64_t val; + int ret; + + ret = _kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO, + attr, &val, false); + if (ret != 0) + return ret; + + val |= 1U << index; + ret = _kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO, + attr, &val, true); + return ret; +} + +void kvm_irq_set_level_info(int gic_fd, uint32_t intid, int level) +{ + int ret = _kvm_irq_set_level_info(gic_fd, intid, level); + + TEST_ASSERT(ret == 0, "KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO failed, " + "rc: %i errno: %i", ret, errno); +} + +int _kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level) +{ + uint32_t irq = intid & KVM_ARM_IRQ_NUM_MASK; + + if (INTID_IS_PPI(intid)) + irq |= KVM_ARM_IRQ_TYPE_PPI << KVM_ARM_IRQ_TYPE_SHIFT; + else if (INTID_IS_SPI(intid)) + irq |= KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT; + else + TEST_FAIL("KVM_IRQ_LINE can't be used with SGIs."); + + return _kvm_irq_line(vm, irq, level); +} + +void kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level) +{ + int ret = _kvm_arm_irq_line(vm, intid, level); + + TEST_ASSERT(ret == 0, "KVM_IRQ_LINE failed, rc: %i errno: %i", + ret, errno); +} + +static void vgic_poke_irq(int gic_fd, uint32_t intid, + uint32_t vcpu, uint64_t reg_off) +{ + uint64_t reg = intid / 32; + uint64_t index = intid % 32; + uint64_t attr = reg_off + reg * 4; + uint64_t val; + bool intid_is_private = INTID_IS_SGI(intid) || INTID_IS_PPI(intid); + + /* Check that the addr part of the attr is within 32 bits. */ + assert(attr <= KVM_DEV_ARM_VGIC_OFFSET_MASK); + + uint32_t group = intid_is_private ? KVM_DEV_ARM_VGIC_GRP_REDIST_REGS + : KVM_DEV_ARM_VGIC_GRP_DIST_REGS; + + if (intid_is_private) { + /* TODO: only vcpu 0 implemented for now. */ + assert(vcpu == 0); + attr += SZ_64K; + } + + /* All calls will succeed, even with invalid intid's, as long as the + * addr part of the attr is within 32 bits (checked above). An invalid + * intid will just make the read/writes point to above the intended + * register space (i.e., ICPENDR after ISPENDR). + */ + kvm_device_access(gic_fd, group, attr, &val, false); + val |= 1ULL << index; + kvm_device_access(gic_fd, group, attr, &val, true); +} + +void kvm_irq_write_ispendr(int gic_fd, uint32_t intid, uint32_t vcpu) +{ + vgic_poke_irq(gic_fd, intid, vcpu, GICD_ISPENDR); +} + +void kvm_irq_write_isactiver(int gic_fd, uint32_t intid, uint32_t vcpu) +{ + vgic_poke_irq(gic_fd, intid, vcpu, GICD_ISACTIVER); +} From patchwork Tue Nov 9 02:38:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19060C433F5 for ; Tue, 9 Nov 2021 02:39:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0737D619BB for ; Tue, 9 Nov 2021 02:39:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241798AbhKICmL (ORCPT ); Mon, 8 Nov 2021 21:42:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241509AbhKICmI (ORCPT ); Mon, 8 Nov 2021 21:42:08 -0500 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 325A0C061570 for ; Mon, 8 Nov 2021 18:39:23 -0800 (PST) Received: by mail-pg1-x549.google.com with SMTP id w5-20020a654105000000b002692534afceso11284913pgp.8 for ; Mon, 08 Nov 2021 18:39:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=IFKj1RFpwXrhz0wYJvIT5CfUbp9nQu7H3z0fbBWNC6U=; b=sQpZotyapzi1P1RAEKkD/WirTgWCKCuS05w7aE+12Yly8SVrI8KCNK3kYmVM9nPUa6 NdW0YXtG2zQ+iEA0sneSNN245ySwYUPGe8TCdlPreg8RGRBs8vNusrjouzxPZswGXjNh B/CPVS68j0XLy8fzQkFYyMuR//s2mzzuE92pLEud37rSCNSm49NpB2rVP+SnBDD9kMod oSufjWpsIKDB3PLpzIuOermS5emUc8FA/u4zuTpt+xHE/Nfu4T5mGt7/uvgpKJ6WrVuC hgj3ZxX6sIE1oeJCRhDMAB8DFeEiCZ/XRLAJYRRU0tPoOwP3BuyM7IDZISKmNN/Sh751 1UJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IFKj1RFpwXrhz0wYJvIT5CfUbp9nQu7H3z0fbBWNC6U=; b=2okqUlPX3Vu7k6yg9OLAp3HjvH1RBVk9QzK9bn1CJYYuB4/4F+H1fhg6HriXWdxzFs Ji9Ia6tGxqtT2POysOTh22RuCDaoF8cm3x6PeKt5cy7czROCl3vL4QlOegbjnzCRVLTv dexU96kcVrg9tY6Xsqst5HUEwWO89QYEVyiu9SqSOJzv9JzSfNxzD3e0H3mXddhOGu+V PYS1B4dlF+Qf+r8eySOkbdiFn7LFNUuYkZFykWX62CYWBAM37XiL/uJ+JWuHnbSFjiuG TCXFJgZPAJkeHNKmouVkLidVwt4SH87yyUjueuszH6zt4zREib0N6Ha4aSOAcukDE1Xv pyOQ== X-Gm-Message-State: AOAM532Do/6mCz0oyo2AiOuDreOZdHMM2dseWesq/n0drPT0yU2Vo/8V yF9fhmhTP/NONqX7nEpVflykLS0BMIJ2Nku9RQk/d0OscCMRX4SOiuqCD9oHlwwODEJA0Lif/kO 07EUXiiyoJVhnzNSkEDBPkeTUQPllEGVFIapdHemztOlVVP/OGauZT0O1R3TLtwQ= X-Google-Smtp-Source: ABdhPJxoX3l9V9y/4/BZ2HTvcdnviEgNfgz4hnyiwqcWSrazR8qgO9XxTQjpsnTyOj293mSrFpcRKeBy6XYVCw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:903:2306:b0:142:123a:24ec with SMTP id d6-20020a170903230600b00142123a24ecmr3958836plh.21.1636425562596; Mon, 08 Nov 2021 18:39:22 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:55 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-7-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 06/17] KVM: selftests: aarch64: add vgic_irq to test userspace IRQ injection From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a new KVM selftest, vgic_irq, for testing userspace IRQ injection. This particular test injects an SPI using KVM_IRQ_LINE on GICv3 and verifies that the IRQ is handled in the guest. The next commits will add more types of IRQs and different modes. Signed-off-by: Ricardo Koller --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../testing/selftests/kvm/aarch64/vgic_irq.c | 244 ++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/vgic_irq.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index d4a830139683..7e59c94f8502 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -4,6 +4,7 @@ /aarch64/get-reg-list /aarch64/psci_cpu_on_test /aarch64/vgic_init +/aarch64/vgic_irq /s390x/memop /s390x/resets /s390x/sync_regs_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index c23e89dea0b6..b90e1c9f7c8d 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -93,6 +93,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test TEST_GEN_PROGS_aarch64 += aarch64/vgic_init +TEST_GEN_PROGS_aarch64 += aarch64/vgic_irq TEST_GEN_PROGS_aarch64 += demand_paging_test TEST_GEN_PROGS_aarch64 += dirty_log_test TEST_GEN_PROGS_aarch64 += dirty_log_perf_test diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c new file mode 100644 index 000000000000..e13e87427038 --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * vgic_irq.c - Test userspace injection of IRQs + * + * This test validates the injection of IRQs from userspace using various + * methods (e.g., KVM_IRQ_LINE) and modes (e.g., EOI). The guest "asks" the + * host to inject a specific intid via a GUEST_SYNC call, and then checks that + * it received it. + */ + +#include +#include +#include + +#include "processor.h" +#include "test_util.h" +#include "kvm_util.h" +#include "gic.h" +#include "gic_v3.h" +#include "vgic.h" + +#define GICD_BASE_GPA 0x08000000ULL +#define GICR_BASE_GPA 0x080A0000ULL +#define VCPU_ID 0 + +/* + * KVM implements 32 priority levels: + * 0x00 (highest priority) - 0xF8 (lowest priority), in steps of 8 + * + * Note that these macros will still be correct in the case that KVM implements + * more priority levels. Also note that 32 is the minimum for GICv3 and GICv2. + */ +#define KVM_NUM_PRIOS 32 +#define KVM_PRIO_SHIFT 3 /* steps of 8 = 1 << 3 */ +#define LOWEST_PRIO (KVM_NUM_PRIOS - 1) +#define CPU_PRIO_MASK (LOWEST_PRIO << KVM_PRIO_SHIFT) /* 0xf8 */ +#define IRQ_DEFAULT_PRIO (LOWEST_PRIO - 1) +#define IRQ_DEFAULT_PRIO_REG (IRQ_DEFAULT_PRIO << KVM_PRIO_SHIFT) /* 0xf0 */ + +static void *dist = (void *)GICD_BASE_GPA; +static void *redist = (void *)GICR_BASE_GPA; + +/* + * The kvm_inject_* utilities are used by the guest to ask the host to inject + * interrupts (e.g., using the KVM_IRQ_LINE ioctl). + */ + +typedef enum { + KVM_INJECT_EDGE_IRQ_LINE = 1, +} kvm_inject_cmd; + +struct kvm_inject_args { + kvm_inject_cmd cmd; + uint32_t intid; +}; + +/* Used on the guest side to perform the hypercall. */ +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t intid); + +/* Used on the host side to get the hypercall info. */ +static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, + struct kvm_inject_args *args); + +/* Shared between the guest main thread and the IRQ handlers. */ +volatile uint64_t irq_handled; +volatile uint32_t irqnr_received[MAX_SPI + 1]; + +static void reset_stats(void) +{ + int i; + + irq_handled = 0; + for (i = 0; i <= MAX_SPI; i++) + irqnr_received[i] = 0; +} + +static uint64_t gic_read_ap1r0(void) +{ + uint64_t reg = read_sysreg_s(SYS_ICV_AP1R0_EL1); + + dsb(sy); + return reg; +} + +static void guest_irq_handler(struct ex_regs *regs) +{ + uint32_t intid = gic_get_and_ack_irq(); + + if (intid == IAR_SPURIOUS) + return; + + GUEST_ASSERT(gic_irq_get_active(intid)); + + GUEST_ASSERT(!gic_irq_get_pending(intid)); + + GUEST_ASSERT(intid < MAX_SPI); + irqnr_received[intid] += 1; + irq_handled += 1; + + gic_set_eoi(intid); + GUEST_ASSERT_EQ(gic_read_ap1r0(), 0); + + GUEST_ASSERT(!gic_irq_get_active(intid)); + GUEST_ASSERT(!gic_irq_get_pending(intid)); +} + +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t intid) +{ + struct kvm_inject_args args = { + .cmd = cmd, + .intid = intid, + }; + GUEST_SYNC(&args); +} + +#define GUEST_ASSERT_IAR_EMPTY() \ +do { \ + uint32_t _intid; \ + _intid = gic_get_and_ack_irq(); \ + GUEST_ASSERT(_intid == 0 || _intid == IAR_SPURIOUS); \ +} while (0) + +static void test_kvm_irq_line(uint32_t intid) +{ + reset_stats(); + + asm volatile("msr daifset, #2" : : : "memory"); + kvm_inject_call(KVM_INJECT_EDGE_IRQ_LINE, intid); + + while (irq_handled < 1) { + asm volatile("wfi\n" + "msr daifclr, #2\n" + /* handle IRQ */ + "msr daifset, #2\n" + : : : "memory"); + } + asm volatile("msr daifclr, #2" : : : "memory"); + + GUEST_ASSERT_EQ(irq_handled, 1); + GUEST_ASSERT_EQ(irqnr_received[intid], 1); + GUEST_ASSERT_IAR_EMPTY(); +} + +static void guest_code(void) +{ + uint32_t i; + uint32_t nr_irqs = 64; /* absolute minimum number of IRQs supported. */ + + gic_init(GIC_V3, 1, dist, redist); + + for (i = 0; i < nr_irqs; i++) { + gic_irq_enable(i); + gic_set_priority(i, IRQ_DEFAULT_PRIO_REG); + } + + gic_set_priority_mask(CPU_PRIO_MASK); + + local_irq_enable(); + + test_kvm_irq_line(MIN_SPI); + + GUEST_DONE(); +} + +static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, + struct kvm_inject_args *inject_args) +{ + kvm_inject_cmd cmd = inject_args->cmd; + uint32_t intid = inject_args->intid; + + switch (cmd) { + case KVM_INJECT_EDGE_IRQ_LINE: + kvm_arm_irq_line(vm, intid, 1); + kvm_arm_irq_line(vm, intid, 0); + break; + default: + break; + } +} + +static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, + struct kvm_inject_args *args) +{ + struct kvm_inject_args *kvm_args_hva; + vm_vaddr_t kvm_args_gva; + + kvm_args_gva = uc->args[1]; + kvm_args_hva = (struct kvm_inject_args *)addr_gva2hva(vm, kvm_args_gva); + memcpy(args, kvm_args_hva, sizeof(struct kvm_inject_args)); +} + + +static void test_vgic(void) +{ + struct ucall uc; + int gic_fd; + struct kvm_vm *vm; + struct kvm_inject_args inject_args; + + 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); + + gic_fd = vgic_v3_setup(vm, 1, GICD_BASE_GPA, GICR_BASE_GPA); + + vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, + guest_irq_handler); + + while (1) { + vcpu_run(vm, VCPU_ID); + + switch (get_ucall(vm, VCPU_ID, &uc)) { + case UCALL_SYNC: + kvm_inject_get_call(vm, &uc, &inject_args); + run_guest_cmd(vm, gic_fd, &inject_args); + 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: + close(gic_fd); + kvm_vm_free(vm); +} + +int main(int ac, char **av) +{ + /* Tell stdout not to buffer its content */ + setbuf(stdout, NULL); + + test_vgic(); + + return 0; +} From patchwork Tue Nov 9 02:38:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8EF65C433FE for ; Tue, 9 Nov 2021 02:39:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 75773619E8 for ; Tue, 9 Nov 2021 02:39:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241751AbhKICmM (ORCPT ); Mon, 8 Nov 2021 21:42:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241630AbhKICmJ (ORCPT ); Mon, 8 Nov 2021 21:42:09 -0500 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 92C53C061570 for ; Mon, 8 Nov 2021 18:39:24 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id y124-20020a623282000000b0047a09271e49so11968934pfy.16 for ; Mon, 08 Nov 2021 18:39:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ncjLEDYXfGn2mZ4JYj7zy7HLzUBwrfGKWWDFG4IBv6o=; b=Bl8Pm0ozKWM/LDLCA6K2BTKtoz58AP9+G+MiKh3oXnapRhrLqyXijXPDxepDOoJjho gwMqsbUylDu4bN1rhqZqClU65UZBpuqXGtMhHeuqy0oEeNQIlAQ7i4Bgo+2/ntB3CqXz oHc3ByRBe274NlJR4dyWfNt1jlm0F6efB0XjITVhWdiYm346FIHCozlgDoimpVUrsl/c 4Ds0Wdc037JHHxU+uPQhzgdnd7c8e/+i+WJFu7NGXwsJ/LJ6qgRFifnbNnHPGZSieJyF P39musL3Jv+1mx2at5ycPfjgCGq6NYnKw1zTFnUDtVO74aD1m6LPfNqoq+PfUxVar/vu Nd7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ncjLEDYXfGn2mZ4JYj7zy7HLzUBwrfGKWWDFG4IBv6o=; b=GIXKoVBZBUfU5rsX1KJ+QDTMDESZ41oyvLRWg7KEBfd/cKbggqzJkrGEUSdFLojde2 KC/DLlKZUoFxdWMU2U+8X2nXaPmuZPCGp7yKhhvaoOlH5fWfGGG+UeK7FDdy/B1+9efb jx//5FgqgbTdoMrWgseq3Wlp/xIzuPO97U06QPuVOHYSbKn6nao2Uh3BDdp2xtFLAdoC rLfjh98XCobT/vnX1jLUE4dBaQLhQP7xJnh6c57smXrAqW9LZi1safQ93rDsoZVRexba EKkRBLNVpfcQuu2hEdVWXYT6KDqJJJNvI+49QowE46oIIaaE3/Ogl3JDgsWbIH6Y5uG5 4U+g== X-Gm-Message-State: AOAM530pDbPUA05uqgcQQbrjVQ1iNN1jhQryR2tU+7lDbu06WWSbaA3d 06/pUMx497HYfVbypltXmgNW6qwa7xF5ax6WXQdAtPpJwgxze3hdlOt+9V09JdsLdpUZfUyJBbo WqovJV6y1xRPqK6IQlnKZdv5GT/v2TIZAcrm/RaEAtJFoOThfuDx1qTODqhR0V9w= X-Google-Smtp-Source: ABdhPJx2kMz7ovig+XiKxpSShdq7aHjbFgtxozevvbz4f2HNg2/3JEyOFbLVPit84lmx/ErpG4ZdqScxc4iHTQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a62:ea16:0:b0:47b:f3d7:7a9 with SMTP id t22-20020a62ea16000000b0047bf3d707a9mr4400254pfh.60.1636425564008; Mon, 08 Nov 2021 18:39:24 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:56 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-8-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 07/17] KVM: selftests: aarch64: abstract the injection functions in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Build an abstraction around the injection functions, so the preparation and checking around the actual injection can be shared between tests. All functions are stored as pointers in arrays of kvm_inject_desc's which include the pointer and what kind of interrupts they can inject. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index e13e87427038..f5d76fef22f0 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -57,10 +57,28 @@ struct kvm_inject_args { /* Used on the guest side to perform the hypercall. */ static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t intid); +#define KVM_INJECT(cmd, intid) \ + kvm_inject_call(cmd, intid) + /* Used on the host side to get the hypercall info. */ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, struct kvm_inject_args *args); +struct kvm_inject_desc { + kvm_inject_cmd cmd; + /* can inject PPIs, PPIs, and/or SPIs. */ + bool sgi, ppi, spi; +}; + +static struct kvm_inject_desc inject_edge_fns[] = { + /* sgi ppi spi */ + { KVM_INJECT_EDGE_IRQ_LINE, false, false, true }, + { 0, }, +}; + +#define for_each_inject_fn(t, f) \ + for ((f) = (t); (f)->cmd; (f)++) + /* Shared between the guest main thread and the IRQ handlers. */ volatile uint64_t irq_handled; volatile uint32_t irqnr_received[MAX_SPI + 1]; @@ -120,12 +138,12 @@ do { \ GUEST_ASSERT(_intid == 0 || _intid == IAR_SPURIOUS); \ } while (0) -static void test_kvm_irq_line(uint32_t intid) +static void guest_inject(uint32_t intid, kvm_inject_cmd cmd) { reset_stats(); asm volatile("msr daifset, #2" : : : "memory"); - kvm_inject_call(KVM_INJECT_EDGE_IRQ_LINE, intid); + KVM_INJECT(cmd, intid); while (irq_handled < 1) { asm volatile("wfi\n" @@ -141,10 +159,23 @@ static void test_kvm_irq_line(uint32_t intid) GUEST_ASSERT_IAR_EMPTY(); } +static void test_injection(struct kvm_inject_desc *f) +{ + if (f->sgi) + guest_inject(MIN_SGI, f->cmd); + + if (f->ppi) + guest_inject(MIN_PPI, f->cmd); + + if (f->spi) + guest_inject(MIN_SPI, f->cmd); +} + static void guest_code(void) { uint32_t i; uint32_t nr_irqs = 64; /* absolute minimum number of IRQs supported. */ + struct kvm_inject_desc *f; gic_init(GIC_V3, 1, dist, redist); @@ -157,7 +188,9 @@ static void guest_code(void) local_irq_enable(); - test_kvm_irq_line(MIN_SPI); + /* Start the tests. */ + for_each_inject_fn(inject_edge_fns, f) + test_injection(f); GUEST_DONE(); } From patchwork Tue Nov 9 02:38:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609605 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7AB32C433F5 for ; Tue, 9 Nov 2021 02:39:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 671FD619BB for ; Tue, 9 Nov 2021 02:39:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241797AbhKICmN (ORCPT ); Mon, 8 Nov 2021 21:42:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241555AbhKICmL (ORCPT ); Mon, 8 Nov 2021 21:42:11 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 227DCC061764 for ; Mon, 8 Nov 2021 18:39:26 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id u10-20020a170902e80a00b001421d86afc4so7280492plg.9 for ; Mon, 08 Nov 2021 18:39:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=T/U2YZ0Dx5Q+ABkERIkOVQhmFwsBS+/GEeXojMLJ6pM=; b=I9J44Tlj1l6UKaQ512FvPEzcX1DdGwiz58SWeR+hdVcMW2kTX45ThPl1NP6G3YkSSt RzLiXAjoBnLW1ZE2M2dz2sGGmToLOxHF5C4ZN1awF2Dyt1EEoelXsL7P8NYCsjkejH/k FAtj8Zj5iWIHfoTIPzEh6lbXozLXbezmh5WFayZnOdaK/SQXvVdVBpwN0fCcmXD1scvb Qb7YvoezFgijKnE8C33RITHSDvk70+mTZyff6dxhO+sKFXeO1Ld/ByXOxp6paFfNLVtC 3KRS7LOAuqVG+GnxgDzQtcVhbett80WMnoidKPgDHvbgX6YSN3OAU1H7+GHzssfC9pYk rfdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=T/U2YZ0Dx5Q+ABkERIkOVQhmFwsBS+/GEeXojMLJ6pM=; b=bvYpgfW9e3AsiCwqcoH0eZVVfJaTAK7Cv5KNqPzMDjFxDTsf9sBuQF81+kGavSAnC5 vH7dnGeoeZvbjYmOiE7K63kgZZ9C48vJy0HxPKAbY4RL5SBCSVkEKxZd+miV6lOTHQ7d IawFYM4jlhF3tTR5HW4CrdTNP7A4FsRuWXtAwftnbFQALI3S6oYKmt1zWrhbIsfjGiDb ocxifUnvpvg9KAWIVJhz/P3YEh0T3lNtIFOoJoeOMsvpGlEyXnbWSkUT5EIyIcneEpR0 tewm/PplkueObKRrSS5jvPzoBnjblb9vcZvudA/dFT21XyY6m+jWQeTJiETZotW/dYo0 p7ow== X-Gm-Message-State: AOAM530hObRMz3oKpY2oysuN0nwu/iM0Mq8bb60rhEq5MCMVW02TCDP2 GgNgoAcL259LQdv3a/eT1aX3k+4z/8yL5w1Arjl3VGu5RaGWoTKhhBXWy2+1UGH5jT8BAnz18IP HZvYRMaSTI/WxcrfzfDBrXbUfi49vEK8KIz2HtI3ZWuA+3GcS+ow0ZzRVQ+/dpP8= X-Google-Smtp-Source: ABdhPJwo5kDWZp3jsZeKBNmmEeBsUziLE7T5cLkpXYrOwjklN8hbYdHReieIXQbhBJdxHHGG9LZhGj4w72n6sg== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90b:4ace:: with SMTP id mh14mr3347384pjb.164.1636425565565; Mon, 08 Nov 2021 18:39:25 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:57 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-9-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 08/17] KVM: selftests: aarch64: cmdline arg to set number of IRQs in vgic_irq test From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add the ability to specify the number of vIRQs exposed by KVM (arg defaults to 64). Then extend the KVM_IRQ_LINE test by injecting all available SPIs at once (specified by the nr-irqs arg). As a bonus, inject all SGIs at once as well. Signed-off-by: Ricardo Koller --- .../selftests/kvm/aarch64/arch_timer.c | 2 +- .../testing/selftests/kvm/aarch64/vgic_irq.c | 149 ++++++++++++++---- .../selftests/kvm/include/aarch64/vgic.h | 2 +- .../testing/selftests/kvm/lib/aarch64/vgic.c | 9 +- 4 files changed, 127 insertions(+), 35 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c index bf6a45b0b8dc..9ad38bd360a4 100644 --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c @@ -382,7 +382,7 @@ static struct kvm_vm *test_vm_create(void) ucall_init(vm, NULL); test_init_timer_irq(vm); - vgic_v3_setup(vm, nr_vcpus, GICD_BASE_GPA, GICR_BASE_GPA); + vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA); /* Make all the test's cmdline args visible to the guest */ sync_global_to_guest(vm, test_args); diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index f5d76fef22f0..0b89a29dfe79 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -23,6 +23,14 @@ #define GICR_BASE_GPA 0x080A0000ULL #define VCPU_ID 0 +/* + * Stores the user specified args; it's passed to the guest and to every test + * function. + */ +struct test_args { + uint32_t nr_irqs; /* number of KVM supported IRQs. */ +}; + /* * KVM implements 32 priority levels: * 0x00 (highest priority) - 0xF8 (lowest priority), in steps of 8 @@ -51,14 +59,18 @@ typedef enum { struct kvm_inject_args { kvm_inject_cmd cmd; - uint32_t intid; + uint32_t first_intid; + uint32_t num; }; /* Used on the guest side to perform the hypercall. */ -static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t intid); +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, uint32_t num); #define KVM_INJECT(cmd, intid) \ - kvm_inject_call(cmd, intid) + kvm_inject_call(cmd, intid, 1) + +#define KVM_INJECT_MULTI(cmd, intid, num) \ + kvm_inject_call(cmd, intid, num) /* Used on the host side to get the hypercall info. */ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, @@ -122,11 +134,12 @@ static void guest_irq_handler(struct ex_regs *regs) GUEST_ASSERT(!gic_irq_get_pending(intid)); } -static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t intid) +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, uint32_t num) { struct kvm_inject_args args = { .cmd = cmd, - .intid = intid, + .first_intid = first_intid, + .num = num, }; GUEST_SYNC(&args); } @@ -138,14 +151,30 @@ do { \ GUEST_ASSERT(_intid == 0 || _intid == IAR_SPURIOUS); \ } while (0) -static void guest_inject(uint32_t intid, kvm_inject_cmd cmd) +static void reset_priorities(struct test_args *args) +{ + int i; + + for (i = 0; i < args->nr_irqs; i++) + gic_set_priority(i, IRQ_DEFAULT_PRIO_REG); +} + +static void guest_inject(struct test_args *args, + uint32_t first_intid, uint32_t num, + kvm_inject_cmd cmd) { + uint32_t i; + reset_stats(); + /* Cycle over all priorities to make things more interesting. */ + for (i = first_intid; i < num + first_intid; i++) + gic_set_priority(i, (i % (KVM_NUM_PRIOS - 1)) << 3); + asm volatile("msr daifset, #2" : : : "memory"); - KVM_INJECT(cmd, intid); + KVM_INJECT_MULTI(cmd, first_intid, num); - while (irq_handled < 1) { + while (irq_handled < num) { asm volatile("wfi\n" "msr daifclr, #2\n" /* handle IRQ */ @@ -154,57 +183,72 @@ static void guest_inject(uint32_t intid, kvm_inject_cmd cmd) } asm volatile("msr daifclr, #2" : : : "memory"); - GUEST_ASSERT_EQ(irq_handled, 1); - GUEST_ASSERT_EQ(irqnr_received[intid], 1); + GUEST_ASSERT_EQ(irq_handled, num); + for (i = first_intid; i < num + first_intid; i++) + GUEST_ASSERT_EQ(irqnr_received[i], 1); GUEST_ASSERT_IAR_EMPTY(); + + reset_priorities(args); } -static void test_injection(struct kvm_inject_desc *f) +static void test_injection(struct test_args *args, struct kvm_inject_desc *f) { - if (f->sgi) - guest_inject(MIN_SGI, f->cmd); + uint32_t nr_irqs = args->nr_irqs; + + if (f->sgi) { + guest_inject(args, MIN_SGI, 1, f->cmd); + guest_inject(args, 0, 16, f->cmd); + } if (f->ppi) - guest_inject(MIN_PPI, f->cmd); + guest_inject(args, MIN_PPI, 1, f->cmd); - if (f->spi) - guest_inject(MIN_SPI, f->cmd); + if (f->spi) { + guest_inject(args, MIN_SPI, 1, f->cmd); + guest_inject(args, nr_irqs - 1, 1, f->cmd); + guest_inject(args, MIN_SPI, nr_irqs - MIN_SPI, f->cmd); + } } -static void guest_code(void) +static void guest_code(struct test_args args) { - uint32_t i; - uint32_t nr_irqs = 64; /* absolute minimum number of IRQs supported. */ + uint32_t i, nr_irqs = args.nr_irqs; struct kvm_inject_desc *f; gic_init(GIC_V3, 1, dist, redist); - for (i = 0; i < nr_irqs; i++) { + for (i = 0; i < nr_irqs; i++) gic_irq_enable(i); - gic_set_priority(i, IRQ_DEFAULT_PRIO_REG); - } + reset_priorities(&args); gic_set_priority_mask(CPU_PRIO_MASK); local_irq_enable(); /* Start the tests. */ for_each_inject_fn(inject_edge_fns, f) - test_injection(f); + test_injection(&args, f); GUEST_DONE(); } static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, - struct kvm_inject_args *inject_args) + struct kvm_inject_args *inject_args, + struct test_args *test_args) { kvm_inject_cmd cmd = inject_args->cmd; - uint32_t intid = inject_args->intid; + uint32_t intid = inject_args->first_intid; + uint32_t num = inject_args->num; + uint32_t i; + + assert(intid < UINT_MAX - num); switch (cmd) { case KVM_INJECT_EDGE_IRQ_LINE: - kvm_arm_irq_line(vm, intid, 1); - kvm_arm_irq_line(vm, intid, 0); + for (i = intid; i < intid + num; i++) + kvm_arm_irq_line(vm, i, 1); + for (i = intid; i < intid + num; i++) + kvm_arm_irq_line(vm, i, 0); break; default: break; @@ -222,21 +266,35 @@ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, memcpy(args, kvm_args_hva, sizeof(struct kvm_inject_args)); } +static void print_args(struct test_args *args) +{ + printf("nr-irqs=%d\n", args->nr_irqs); +} -static void test_vgic(void) +static void test_vgic(uint32_t nr_irqs) { struct ucall uc; int gic_fd; struct kvm_vm *vm; struct kvm_inject_args inject_args; + struct test_args args = { + .nr_irqs = nr_irqs, + }; + + print_args(&args); + 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); - gic_fd = vgic_v3_setup(vm, 1, GICD_BASE_GPA, GICR_BASE_GPA); + /* Setup the guest args page (so it gets the args). */ + vcpu_args_set(vm, 0, 1, args); + + gic_fd = vgic_v3_setup(vm, 1, nr_irqs, + GICD_BASE_GPA, GICR_BASE_GPA); vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, guest_irq_handler); @@ -247,7 +305,7 @@ static void test_vgic(void) switch (get_ucall(vm, VCPU_ID, &uc)) { case UCALL_SYNC: kvm_inject_get_call(vm, &uc, &inject_args); - run_guest_cmd(vm, gic_fd, &inject_args); + run_guest_cmd(vm, gic_fd, &inject_args, &args); break; case UCALL_ABORT: TEST_FAIL("%s at %s:%ld\n\tvalues: %#lx, %#lx", @@ -266,12 +324,39 @@ static void test_vgic(void) kvm_vm_free(vm); } -int main(int ac, char **av) +static void help(const char *name) { + printf( + "\n" + "usage: %s [-n num_irqs]\n", name); + printf(" -n: specify the number of IRQs to configure the vgic with.\n"); + puts(""); + exit(1); +} + +int main(int argc, char **argv) +{ + uint32_t nr_irqs = 64; + int opt; + /* Tell stdout not to buffer its content */ setbuf(stdout, NULL); - test_vgic(); + while ((opt = getopt(argc, argv, "hg:n:")) != -1) { + switch (opt) { + case 'n': + nr_irqs = atoi(optarg); + if (nr_irqs > 1024 || nr_irqs % 32) + help(argv[0]); + break; + case 'h': + default: + help(argv[0]); + break; + } + } + + test_vgic(nr_irqs); return 0; } diff --git a/tools/testing/selftests/kvm/include/aarch64/vgic.h b/tools/testing/selftests/kvm/include/aarch64/vgic.h index ec8744bb2d4b..ce6f0383c1a1 100644 --- a/tools/testing/selftests/kvm/include/aarch64/vgic.h +++ b/tools/testing/selftests/kvm/include/aarch64/vgic.h @@ -14,7 +14,7 @@ ((uint64_t)(flags) << 12) | \ index) -int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, +int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs, uint64_t gicd_base_gpa, uint64_t gicr_base_gpa); #define VGIC_MAX_RESERVED 1023 diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c index a1f1f6c8e2e0..84206d7c92b4 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c @@ -31,7 +31,7 @@ * redistributor regions of the guest. Since it depends on the number of * vCPUs for the VM, it must be called after all the vCPUs have been created. */ -int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, +int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs, uint64_t gicd_base_gpa, uint64_t gicr_base_gpa) { int gic_fd; @@ -53,6 +53,13 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, /* Distributor setup */ gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false); + + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, + 0, &nr_irqs, true); + + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, + KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true); + kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST, &gicd_base_gpa, true); nr_gic_pages = vm_calc_num_guest_pages(vm->mode, KVM_VGIC_V3_DIST_SIZE); From patchwork Tue Nov 9 02:38:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94221C4332F for ; Tue, 9 Nov 2021 02:39:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7FB87619BB for ; Tue, 9 Nov 2021 02:39:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241828AbhKICmO (ORCPT ); Mon, 8 Nov 2021 21:42:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241775AbhKICmN (ORCPT ); Mon, 8 Nov 2021 21:42:13 -0500 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64854C061570 for ; Mon, 8 Nov 2021 18:39:28 -0800 (PST) Received: by mail-pf1-x44a.google.com with SMTP id s22-20020a056a0008d600b00480fea2e96cso11984353pfu.7 for ; Mon, 08 Nov 2021 18:39:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7PZd0x6lPt+COIUe7s6j5utQGrhaF5ukxN/0RXAhVWo=; b=KkxlOHxbD8sX4/BavdqqOCubN6USToniJ7DdIIAxOUptOkCQavMqqZXwLDQ47hcYxP JFyldCgg3BC3Q6ZzfJ6TjKHhFJ0nr/Xp4z6O1LxiDizBwHCYUSvyC5kmEZgOE4IyjR4T BicOJ+yQdSq9NtYqEyWBjh0Al+TzfTBWifD1N3o5770pW9r2oJBsxgn4fX1O1pAQt7L/ CVo7PvNm8WBKi9+pCuA7lNNGYOgvyBdSlTIXdsDue7T4JhIVJ4Gn5yS46ro0tJHlg6zB qbZS5P5P7EZSI9N/LZNV+VSRUKdXOjmp/K+hR6AD+DBQQ9TmlOpEc7Cc0sCon22wj9Wt 6srg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7PZd0x6lPt+COIUe7s6j5utQGrhaF5ukxN/0RXAhVWo=; b=k/YHb4uf/uN5wRBt9XDhGZ73CIsaF17YBjJA/A61UTu1RokJYEz7gQhYoJ/AOuXibA 1Q1TCYQnx9lIh6HPON1Km8LpTtE96gOUWh+8iZ/um6uHnARWw+xlAlko1U4YVXPsahU2 JzLlRFVaDHmQ6UvI83WG7AWurJ1LH77qh6BS/RZLSeQ0Mh8KNq9A0JrFDSfUSI7QCjZc wn7BzkQY5dOJMPoKl0rSgzftiMuHxUQhauBq3v7h3mlVEzlq0gg7YKTuzIprIAz9K3+Q RVeeTMUDdcgrlwe5xrdgjEG0ByMrxmNbLaXhks8yWH7dQnFvfNaxzb4W47cIznVfEC5U H4UQ== X-Gm-Message-State: AOAM533ml9LQyo0sk5AAOtxiqqRBrw9N4xwHtaJQOFDNPCQDEC+Xpx8s ldIXJgKLaZd2E98XRyYUnd5nxhMFUZoRZgFznGPyjo0GogdPUkAQE7a0iRYC/QrYk/UQOGYaZJK eI6M3RKp5tIKOCYqGrMsqUfWKmEIBPILIkvWf9cIaFTnFTgRr51XBX7Pl2EzaESA= X-Google-Smtp-Source: ABdhPJyZeUY1gD4uhMncXTUXTVCynHHQyEClaB3J19aVo94b9xq6INrEPKCtUNuTetOpfR96X8W9qAtSLlzsKA== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90a:284f:: with SMTP id p15mr137439pjf.1.1636425567125; Mon, 08 Nov 2021 18:39:27 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:58 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-10-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 09/17] KVM: selftests: aarch64: cmdline arg to set EOI mode in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a new cmdline arg to set the EOI mode for all vgic_irq tests. This specifies whether a write to EOIR will deactivate IRQs or not. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 58 ++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index 0b89a29dfe79..3e18fa224280 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -29,6 +29,7 @@ */ struct test_args { uint32_t nr_irqs; /* number of KVM supported IRQs. */ + bool eoi_split; /* 1 is eoir+dir, 0 is eoir only */ }; /* @@ -112,7 +113,7 @@ static uint64_t gic_read_ap1r0(void) return reg; } -static void guest_irq_handler(struct ex_regs *regs) +static void guest_irq_generic_handler(bool eoi_split) { uint32_t intid = gic_get_and_ack_irq(); @@ -129,6 +130,8 @@ static void guest_irq_handler(struct ex_regs *regs) gic_set_eoi(intid); GUEST_ASSERT_EQ(gic_read_ap1r0(), 0); + if (eoi_split) + gic_set_dir(intid); GUEST_ASSERT(!gic_irq_get_active(intid)); GUEST_ASSERT(!gic_irq_get_pending(intid)); @@ -151,6 +154,24 @@ do { \ GUEST_ASSERT(_intid == 0 || _intid == IAR_SPURIOUS); \ } while (0) +#define CAT_HELPER(a, b) a ## b +#define CAT(a, b) CAT_HELPER(a, b) +#define PREFIX guest_irq_handler_ +#define GUEST_IRQ_HANDLER_NAME(split) CAT(PREFIX, split) +#define GENERATE_GUEST_IRQ_HANDLER(split) \ +static void CAT(PREFIX, split)(struct ex_regs *regs) \ +{ \ + guest_irq_generic_handler(split); \ +} + +GENERATE_GUEST_IRQ_HANDLER(0); +GENERATE_GUEST_IRQ_HANDLER(1); + +static void (*guest_irq_handlers[2])(struct ex_regs *) = { + GUEST_IRQ_HANDLER_NAME(0), + GUEST_IRQ_HANDLER_NAME(1), +}; + static void reset_priorities(struct test_args *args) { int i; @@ -220,6 +241,8 @@ static void guest_code(struct test_args args) for (i = 0; i < nr_irqs; i++) gic_irq_enable(i); + gic_set_eoi_split(args.eoi_split); + reset_priorities(&args); gic_set_priority_mask(CPU_PRIO_MASK); @@ -268,10 +291,11 @@ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, static void print_args(struct test_args *args) { - printf("nr-irqs=%d\n", args->nr_irqs); + printf("nr-irqs=%d eoi-split=%d\n", + args->nr_irqs, args->eoi_split); } -static void test_vgic(uint32_t nr_irqs) +static void test_vgic(uint32_t nr_irqs, bool eoi_split) { struct ucall uc; int gic_fd; @@ -280,6 +304,7 @@ static void test_vgic(uint32_t nr_irqs) struct test_args args = { .nr_irqs = nr_irqs, + .eoi_split = eoi_split, }; print_args(&args); @@ -297,7 +322,7 @@ static void test_vgic(uint32_t nr_irqs) GICD_BASE_GPA, GICR_BASE_GPA); vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, - guest_irq_handler); + guest_irq_handlers[args.eoi_split]); while (1) { vcpu_run(vm, VCPU_ID); @@ -328,8 +353,11 @@ static void help(const char *name) { printf( "\n" - "usage: %s [-n num_irqs]\n", name); - printf(" -n: specify the number of IRQs to configure the vgic with.\n"); + "usage: %s [-n num_irqs] [-e eoi_split]\n", name); + printf(" -n: specify the number of IRQs to configure the vgic with. " + "It has to be a multiple of 32 and between 64 and 1024.\n"); + printf(" -e: if 1 then EOI is split into a write to DIR on top " + "of writing EOI.\n"); puts(""); exit(1); } @@ -337,18 +365,24 @@ static void help(const char *name) int main(int argc, char **argv) { uint32_t nr_irqs = 64; + bool default_args = true; int opt; + bool eoi_split = false; /* Tell stdout not to buffer its content */ setbuf(stdout, NULL); - while ((opt = getopt(argc, argv, "hg:n:")) != -1) { + while ((opt = getopt(argc, argv, "hn:e:")) != -1) { switch (opt) { case 'n': nr_irqs = atoi(optarg); if (nr_irqs > 1024 || nr_irqs % 32) help(argv[0]); break; + case 'e': + eoi_split = (bool)atoi(optarg); + default_args = false; + break; case 'h': default: help(argv[0]); @@ -356,7 +390,15 @@ int main(int argc, char **argv) } } - test_vgic(nr_irqs); + /* If the user just specified nr_irqs and/or gic_version, then run all + * combinations. + */ + if (default_args) { + test_vgic(nr_irqs, false /* eoi_split */); + test_vgic(nr_irqs, true /* eoi_split */); + } else { + test_vgic(nr_irqs, eoi_split); + } return 0; } From patchwork Tue Nov 9 02:38:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609609 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C6614C433F5 for ; Tue, 9 Nov 2021 02:39:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B1838619BB for ; Tue, 9 Nov 2021 02:39:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241697AbhKICmS (ORCPT ); Mon, 8 Nov 2021 21:42:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241788AbhKICmO (ORCPT ); Mon, 8 Nov 2021 21:42:14 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B416AC061766 for ; Mon, 8 Nov 2021 18:39:29 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id n13-20020a170902d2cd00b0014228ffc40dso6592104plc.4 for ; Mon, 08 Nov 2021 18:39:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=LozXdBeHm1wVJM1zXtUi3Myaa0mOvHQ8f6t6MIK9jqk=; b=c2JYScEky9XAjrfUtUpSg0+Ds/y5sqhLsY4MTjk1ZRyQ5jTN+xr18kK5ALfBIkdJGl BeTxqMZXPXkFlv4W77QPonZYelqiEfHTUeYu01+VAXEyh4srKCMpNR+w2H9ZSisj6hju 7jgBEmL+2HSlqRH1z1zJQ/QAV2sdf8sCUkO+o8EsS4uAsJECUV0vi3YBRAl3UAKJH0EA HBq6OmaB1EQtEJAPCRn1DJ4qj1NMNQsGDGLtfDzdCihW10n5RBHQl7TDLI5YCYIwKtq3 O2rmB73ClJb40oSoNLany273Jisyaex1z4lIO4QMIMxDWU4lmLzAfD71VVa6calQR9Z3 3BMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=LozXdBeHm1wVJM1zXtUi3Myaa0mOvHQ8f6t6MIK9jqk=; b=COPPFlhVTkiEGlrd7cEfmeMhCsR4ikxy+kDqAi0YkhA5NQ8pscPeMeORTjYXhaTYV1 h+abLhtHDEvYX5j5Gcgj9L1TLGeAqhu4iOE3cQutI99VczcnKy4rdhu5GjLiZ5/6DcHr 6AatFBD8BQ6XE+7qJw11MNKoSmKSEr02C8/8bCuUm5QD57/EmSiClmkKYZY5F7aYtflA b7Cgv2jTh2740c/HoFiTUlWNhDOu9PzLhf8ontV+X8oUQbd0UrbxqtrJ2icQjVUtuHVS yiBZUzA/LY9D0uYy+osD5KJ2wdwc3lgILfaSDZbywpkhaYmf/+CPpuCJhUGA0Np9AG/j Iueg== X-Gm-Message-State: AOAM5331WuMY+ZcX6Ms4mVLh47JBFdgB8Qbp9T/klUvo65lxWkUyZBmz e52aOq25CDud6fnkebwqyKUMX1a+qeIamH9DlVkukUppbC9AHQI1Ka3LjpMAmkdMpsJKrw1M85S uPkSR1xp5toUnwuRpnzcs9cTXweRCg1H8rRpkS10mRMKURQhNBJEq8sZlKizrmVQ= X-Google-Smtp-Source: ABdhPJyd3cmlccdsr0jYFtsQ/AxEtNcZxg4ERBnu9kTbLsShBB+WnJdZ2O9U6SlWXTQFEJZRY28W/+iC5/C0mQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:aa7:8755:0:b0:494:67a6:1c84 with SMTP id g21-20020aa78755000000b0049467a61c84mr37627084pfo.26.1636425569082; Mon, 08 Nov 2021 18:39:29 -0800 (PST) Date: Mon, 8 Nov 2021 18:38:59 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-11-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 10/17] KVM: selftests: aarch64: add preemption tests in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add tests for IRQ preemption (having more than one activated IRQ at the same time). This test injects multiple concurrent IRQs and handles them without handling the actual exceptions. This is done by masking interrupts for the whole test. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 91 ++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index 3e18fa224280..b9080aa75a14 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -41,6 +41,7 @@ struct test_args { */ #define KVM_NUM_PRIOS 32 #define KVM_PRIO_SHIFT 3 /* steps of 8 = 1 << 3 */ +#define KVM_PRIO_STEPS (1 << KVM_PRIO_SHIFT) /* 8 */ #define LOWEST_PRIO (KVM_NUM_PRIOS - 1) #define CPU_PRIO_MASK (LOWEST_PRIO << KVM_PRIO_SHIFT) /* 0xf8 */ #define IRQ_DEFAULT_PRIO (LOWEST_PRIO - 1) @@ -212,6 +213,74 @@ static void guest_inject(struct test_args *args, reset_priorities(args); } +/* + * Polls the IAR until it's not a spurious interrupt. + * + * This function should only be used in test_inject_preemption (with IRQs + * masked). + */ +static uint32_t wait_for_and_activate_irq(void) +{ + uint32_t intid; + + do { + asm volatile("wfi" : : : "memory"); + intid = gic_get_and_ack_irq(); + } while (intid == IAR_SPURIOUS); + + return intid; +} + +/* + * Inject multiple concurrent IRQs (num IRQs starting at first_intid) and + * handle them without handling the actual exceptions. This is done by masking + * interrupts for the whole test. + */ +static void test_inject_preemption(struct test_args *args, + uint32_t first_intid, int num, + kvm_inject_cmd cmd) +{ + uint32_t intid, prio, step = KVM_PRIO_STEPS; + int i; + + /* Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs + * in descending order, so intid+1 can preempt intid. + */ + for (i = 0, prio = (num - 1) * step; i < num; i++, prio -= step) { + GUEST_ASSERT(prio >= 0); + intid = i + first_intid; + gic_set_priority(intid, prio); + } + + local_irq_disable(); + + for (i = 0; i < num; i++) { + uint32_t tmp; + intid = i + first_intid; + kvm_inject_call(cmd, intid, 1); + /* Each successive IRQ will preempt the previous one. */ + tmp = wait_for_and_activate_irq(); + GUEST_ASSERT_EQ(tmp, intid); + } + + /* finish handling the IRQs starting with the highest priority one. */ + for (i = 0; i < num; i++) { + intid = num - i - 1 + first_intid; + gic_set_eoi(intid); + if (args->eoi_split) + gic_set_dir(intid); + } + + local_irq_enable(); + + for (i = 0; i < num; i++) + GUEST_ASSERT(!gic_irq_get_active(i + first_intid)); + GUEST_ASSERT_EQ(gic_read_ap1r0(), 0); + GUEST_ASSERT_IAR_EMPTY(); + + reset_priorities(args); +} + static void test_injection(struct test_args *args, struct kvm_inject_desc *f) { uint32_t nr_irqs = args->nr_irqs; @@ -231,6 +300,24 @@ static void test_injection(struct test_args *args, struct kvm_inject_desc *f) } } +static void test_preemption(struct test_args *args, struct kvm_inject_desc *f) +{ + /* + * Test up to 4 levels of preemption. The reason is that KVM doesn't + * currently implement the ability to have more than the number-of-LRs + * number of concurrently active IRQs. The number of LRs implemented is + * IMPLEMENTATION DEFINED, however, it seems that most implement 4. + */ + if (f->sgi) + test_inject_preemption(args, MIN_SGI, 4, f->cmd); + + if (f->ppi) + test_inject_preemption(args, MIN_PPI, 4, f->cmd); + + if (f->spi) + test_inject_preemption(args, MIN_SPI, 4, f->cmd); +} + static void guest_code(struct test_args args) { uint32_t i, nr_irqs = args.nr_irqs; @@ -249,8 +336,10 @@ static void guest_code(struct test_args args) local_irq_enable(); /* Start the tests. */ - for_each_inject_fn(inject_edge_fns, f) + for_each_inject_fn(inject_edge_fns, f) { test_injection(&args, f); + test_preemption(&args, f); + } GUEST_DONE(); } From patchwork Tue Nov 9 02:39:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76207C433FE for ; Tue, 9 Nov 2021 02:39:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 62FF6619EC for ; Tue, 9 Nov 2021 02:39:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241882AbhKICmT (ORCPT ); Mon, 8 Nov 2021 21:42:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241802AbhKICmQ (ORCPT ); Mon, 8 Nov 2021 21:42:16 -0500 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 0D01FC061570 for ; Mon, 8 Nov 2021 18:39:31 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id j3-20020a628003000000b004811bc66186so11991536pfd.5 for ; Mon, 08 Nov 2021 18:39:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=gm/CRNjGjObMWonwa5W/nHZic3GC4NyZisHGpLvhyc8=; b=jg7R31HslzvC6WTkqWsMFWssSX7fbPtphmW/TRdpNjnirQ3H99s7xKyNOZ84ofrMcA QpzHH9Cnji7GWRlIXp5JGEXTzog5Ltq+nEEdlmq3pH52nHBYgbImdsAhud0GiRPcxIrp GQ6kMjr+G4MAaUcouPEpkQjVe+psk0N6A2x7FVfiPL2Vsz3dH1+q1PeS0Rzby9GAj8UQ OFkP6t6z9bLLEY/KiwlpXBSVlnFku9LBL/hnuXBFaA3/MF2CRRxgBfXhYDmKzT1GS510 TSUzPjuVYH6j4ad9bPukukVLRzpAM8BtvsTIltCKPNBzh7kk0ECuiTKO8OweVkj57dou D3uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gm/CRNjGjObMWonwa5W/nHZic3GC4NyZisHGpLvhyc8=; b=Vnw7Nxp+qJHvEwD4cB9DBad6qB70lCUzuOxqXVIH5Q3jl5Fo7daYhPZl962WwkXLda qM/uoYIBCcQW1SBE0/H2J9yfwpIs7qnrpUi2RZMbnFW936eOhgS0DgKM73rcnunptjVF bYMjzr3M433jx8nS9/WbTlTXZmJVRoYEg0DyJZo0j7OFwh2KCcD/HIF4nDhFv/lXdJ8v Y1r8FZChdxfqquwFxVtsan14OP28/whMlMpu0qYCIbrGfqzuYBtySSYFZ9wlqzw3PFtD ucJJLpdaHWVpfUI4V7sksnBYma77z2gucvfBYn4O6VuVgVjMNE1dpnbcb4ptVopLanzj q45A== X-Gm-Message-State: AOAM530p6rxNpv7RqBL6UgmRDcrCC9/QPj2MKke9DXWSmb5kAHMyK+UW T6D+CEs3KqKv6rIBxEtnoFWrUs9wwiuxfqNU3pJhQG5D+xi293Zd0ltRk5M3Xas9LLcYIcnfOcI p9f3FTXGRuj8DYvGrfgq1uu3/AzeeVFWfa45a9SfEp/EpPe6nsFMzFgIXWMXBizA= X-Google-Smtp-Source: ABdhPJzhJP7M/gay4oj9KOwF1d5OYBITCKFBVyKsSkoXq9DGjtvLfZlQXywp8op82b7ujQciv32QjtD4lcLrIw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:e806:b0:142:830:eaa4 with SMTP id u6-20020a170902e80600b001420830eaa4mr3808196plg.16.1636425570433; Mon, 08 Nov 2021 18:39:30 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:00 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-12-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 11/17] KVM: selftests: aarch64: level-sensitive interrupts tests in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a cmdline arg for using level-sensitive interrupts (vs the default edge-triggered). Then move the handler into a generic handler function that takes the type of interrupt (level vs. edge) as an arg. When handling line-sensitive interrupts it sets the line to low after acknowledging the IRQ. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 118 +++++++++++++----- 1 file changed, 86 insertions(+), 32 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index b9080aa75a14..a20d225367a1 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -30,6 +30,7 @@ struct test_args { uint32_t nr_irqs; /* number of KVM supported IRQs. */ bool eoi_split; /* 1 is eoir+dir, 0 is eoir only */ + bool level_sensitive; /* 1 is level, 0 is edge */ }; /* @@ -57,27 +58,31 @@ static void *redist = (void *)GICR_BASE_GPA; typedef enum { KVM_INJECT_EDGE_IRQ_LINE = 1, + KVM_SET_IRQ_LINE, + KVM_SET_IRQ_LINE_HIGH, } kvm_inject_cmd; struct kvm_inject_args { kvm_inject_cmd cmd; uint32_t first_intid; uint32_t num; + int level; }; /* Used on the guest side to perform the hypercall. */ -static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, uint32_t num); - -#define KVM_INJECT(cmd, intid) \ - kvm_inject_call(cmd, intid, 1) - -#define KVM_INJECT_MULTI(cmd, intid, num) \ - kvm_inject_call(cmd, intid, num) +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, + uint32_t num, int level); /* Used on the host side to get the hypercall info. */ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, struct kvm_inject_args *args); +#define KVM_INJECT(cmd, intid) \ + kvm_inject_call(cmd, intid, 1, -1 /* not used */) + +#define KVM_INJECT_MULTI(cmd, intid, num) \ + kvm_inject_call(cmd, intid, num, -1 /* not used */) + struct kvm_inject_desc { kvm_inject_cmd cmd; /* can inject PPIs, PPIs, and/or SPIs. */ @@ -90,6 +95,12 @@ static struct kvm_inject_desc inject_edge_fns[] = { { 0, }, }; +static struct kvm_inject_desc inject_level_fns[] = { + /* sgi ppi spi */ + { KVM_SET_IRQ_LINE_HIGH, false, true, true }, + { 0, }, +}; + #define for_each_inject_fn(t, f) \ for ((f) = (t); (f)->cmd; (f)++) @@ -114,7 +125,9 @@ static uint64_t gic_read_ap1r0(void) return reg; } -static void guest_irq_generic_handler(bool eoi_split) +static void guest_set_irq_line(uint32_t intid, uint32_t level); + +static void guest_irq_generic_handler(bool eoi_split, bool level_sensitive) { uint32_t intid = gic_get_and_ack_irq(); @@ -123,7 +136,11 @@ static void guest_irq_generic_handler(bool eoi_split) GUEST_ASSERT(gic_irq_get_active(intid)); - GUEST_ASSERT(!gic_irq_get_pending(intid)); + if (!level_sensitive) + GUEST_ASSERT(!gic_irq_get_pending(intid)); + + if (level_sensitive) + guest_set_irq_line(intid, 0); GUEST_ASSERT(intid < MAX_SPI); irqnr_received[intid] += 1; @@ -138,12 +155,14 @@ static void guest_irq_generic_handler(bool eoi_split) GUEST_ASSERT(!gic_irq_get_pending(intid)); } -static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, uint32_t num) +static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, + uint32_t num, int level) { struct kvm_inject_args args = { .cmd = cmd, .first_intid = first_intid, .num = num, + .level = level, }; GUEST_SYNC(&args); } @@ -158,19 +177,21 @@ do { \ #define CAT_HELPER(a, b) a ## b #define CAT(a, b) CAT_HELPER(a, b) #define PREFIX guest_irq_handler_ -#define GUEST_IRQ_HANDLER_NAME(split) CAT(PREFIX, split) -#define GENERATE_GUEST_IRQ_HANDLER(split) \ -static void CAT(PREFIX, split)(struct ex_regs *regs) \ +#define GUEST_IRQ_HANDLER_NAME(split, lev) CAT(PREFIX, CAT(split, lev)) +#define GENERATE_GUEST_IRQ_HANDLER(split, lev) \ +static void CAT(PREFIX, CAT(split, lev))(struct ex_regs *regs) \ { \ - guest_irq_generic_handler(split); \ + guest_irq_generic_handler(split, lev); \ } -GENERATE_GUEST_IRQ_HANDLER(0); -GENERATE_GUEST_IRQ_HANDLER(1); +GENERATE_GUEST_IRQ_HANDLER(0, 0); +GENERATE_GUEST_IRQ_HANDLER(0, 1); +GENERATE_GUEST_IRQ_HANDLER(1, 0); +GENERATE_GUEST_IRQ_HANDLER(1, 1); -static void (*guest_irq_handlers[2])(struct ex_regs *) = { - GUEST_IRQ_HANDLER_NAME(0), - GUEST_IRQ_HANDLER_NAME(1), +static void (*guest_irq_handlers[2][2])(struct ex_regs *) = { + {GUEST_IRQ_HANDLER_NAME(0, 0), GUEST_IRQ_HANDLER_NAME(0, 1),}, + {GUEST_IRQ_HANDLER_NAME(1, 0), GUEST_IRQ_HANDLER_NAME(1, 1),}, }; static void reset_priorities(struct test_args *args) @@ -181,6 +202,11 @@ static void reset_priorities(struct test_args *args) gic_set_priority(i, IRQ_DEFAULT_PRIO_REG); } +static void guest_set_irq_line(uint32_t intid, uint32_t level) +{ + kvm_inject_call(KVM_SET_IRQ_LINE, intid, 1, level); +} + static void guest_inject(struct test_args *args, uint32_t first_intid, uint32_t num, kvm_inject_cmd cmd) @@ -257,10 +283,12 @@ static void test_inject_preemption(struct test_args *args, for (i = 0; i < num; i++) { uint32_t tmp; intid = i + first_intid; - kvm_inject_call(cmd, intid, 1); + KVM_INJECT(cmd, intid); /* Each successive IRQ will preempt the previous one. */ tmp = wait_for_and_activate_irq(); GUEST_ASSERT_EQ(tmp, intid); + if (args->level_sensitive) + guest_set_irq_line(intid, 0); } /* finish handling the IRQs starting with the highest priority one. */ @@ -321,22 +349,29 @@ static void test_preemption(struct test_args *args, struct kvm_inject_desc *f) static void guest_code(struct test_args args) { uint32_t i, nr_irqs = args.nr_irqs; - struct kvm_inject_desc *f; + bool level_sensitive = args.level_sensitive; + struct kvm_inject_desc *f, *inject_fns; gic_init(GIC_V3, 1, dist, redist); for (i = 0; i < nr_irqs; i++) gic_irq_enable(i); + for (i = MIN_SPI; i < nr_irqs; i++) + gic_irq_set_config(i, !args.level_sensitive); + gic_set_eoi_split(args.eoi_split); reset_priorities(&args); gic_set_priority_mask(CPU_PRIO_MASK); + inject_fns = level_sensitive ? inject_level_fns + : inject_edge_fns; + local_irq_enable(); /* Start the tests. */ - for_each_inject_fn(inject_edge_fns, f) { + for_each_inject_fn(inject_fns, f) { test_injection(&args, f); test_preemption(&args, f); } @@ -351,6 +386,7 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, kvm_inject_cmd cmd = inject_args->cmd; uint32_t intid = inject_args->first_intid; uint32_t num = inject_args->num; + int level = inject_args->level; uint32_t i; assert(intid < UINT_MAX - num); @@ -362,6 +398,14 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, for (i = intid; i < intid + num; i++) kvm_arm_irq_line(vm, i, 0); break; + case KVM_SET_IRQ_LINE: + for (i = intid; i < intid + num; i++) + kvm_arm_irq_line(vm, i, level); + break; + case KVM_SET_IRQ_LINE_HIGH: + for (i = intid; i < intid + num; i++) + kvm_arm_irq_line(vm, i, 1); + break; default: break; } @@ -380,11 +424,12 @@ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, static void print_args(struct test_args *args) { - printf("nr-irqs=%d eoi-split=%d\n", - args->nr_irqs, args->eoi_split); + printf("nr-irqs=%d level-sensitive=%d eoi-split=%d\n", + args->nr_irqs, args->level_sensitive, + args->eoi_split); } -static void test_vgic(uint32_t nr_irqs, bool eoi_split) +static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split) { struct ucall uc; int gic_fd; @@ -393,6 +438,7 @@ static void test_vgic(uint32_t nr_irqs, bool eoi_split) struct test_args args = { .nr_irqs = nr_irqs, + .level_sensitive = level_sensitive, .eoi_split = eoi_split, }; @@ -411,7 +457,7 @@ static void test_vgic(uint32_t nr_irqs, bool eoi_split) GICD_BASE_GPA, GICR_BASE_GPA); vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT, - guest_irq_handlers[args.eoi_split]); + guest_irq_handlers[args.eoi_split][args.level_sensitive]); while (1) { vcpu_run(vm, VCPU_ID); @@ -442,11 +488,12 @@ static void help(const char *name) { printf( "\n" - "usage: %s [-n num_irqs] [-e eoi_split]\n", name); - printf(" -n: specify the number of IRQs to configure the vgic with. " + "usage: %s [-n num_irqs] [-e eoi_split] [-l level_sensitive]\n", name); + printf(" -n: specify number of IRQs to setup the vgic with. " "It has to be a multiple of 32 and between 64 and 1024.\n"); printf(" -e: if 1 then EOI is split into a write to DIR on top " "of writing EOI.\n"); + printf(" -l: specify whether the IRQs are level-sensitive (1) or not (0)."); puts(""); exit(1); } @@ -455,13 +502,14 @@ int main(int argc, char **argv) { uint32_t nr_irqs = 64; bool default_args = true; + bool level_sensitive = false; int opt; bool eoi_split = false; /* Tell stdout not to buffer its content */ setbuf(stdout, NULL); - while ((opt = getopt(argc, argv, "hn:e:")) != -1) { + while ((opt = getopt(argc, argv, "hn:e:l:")) != -1) { switch (opt) { case 'n': nr_irqs = atoi(optarg); @@ -472,6 +520,10 @@ int main(int argc, char **argv) eoi_split = (bool)atoi(optarg); default_args = false; break; + case 'l': + level_sensitive = (bool)atoi(optarg); + default_args = false; + break; case 'h': default: help(argv[0]); @@ -483,10 +535,12 @@ int main(int argc, char **argv) * combinations. */ if (default_args) { - test_vgic(nr_irqs, false /* eoi_split */); - test_vgic(nr_irqs, true /* eoi_split */); + test_vgic(nr_irqs, false /* level */, false /* eoi_split */); + test_vgic(nr_irqs, false /* level */, true /* eoi_split */); + test_vgic(nr_irqs, true /* level */, false /* eoi_split */); + test_vgic(nr_irqs, true /* level */, true /* eoi_split */); } else { - test_vgic(nr_irqs, eoi_split); + test_vgic(nr_irqs, level_sensitive, eoi_split); } return 0; From patchwork Tue Nov 9 02:39:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609611 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4BE5EC4332F for ; Tue, 9 Nov 2021 02:39:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 34601619BB for ; Tue, 9 Nov 2021 02:39:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241887AbhKICmU (ORCPT ); Mon, 8 Nov 2021 21:42:20 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241851AbhKICmR (ORCPT ); Mon, 8 Nov 2021 21:42:17 -0500 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9787FC061570 for ; Mon, 8 Nov 2021 18:39:32 -0800 (PST) Received: by mail-pf1-x44a.google.com with SMTP id h21-20020a056a001a5500b0049fc7bcb45aso3609388pfv.11 for ; Mon, 08 Nov 2021 18:39:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=iSH/9G2uxswFP6gkGEcQmnNa2z9g8VsdxM33bZx7bv0=; b=FNjNDlAP3hOxMC/RXn9EWgjxrA+hIShK3UY3VETSZOuZMJeHfitIHtJQZxvYQV+f4U Iq/swVyJQEUWRDtuU2WQYypz+xyoRoUfhUzx1kek+cHBteUTCGFdth6d4o6Jm9n+oucZ IgoKaTYNOIpCsOLYhKXDyHd84maT9VxoAsHSFqznaArbX9+6iESd9y9zxcDsBrepK7d0 GFpAwakViIFKPT+Pu2ZrImzM9CtXEOk0XhW/XpnbXOWGZpw3X5sIb0Ftm0Cql2xNDzRI dpBpmZhwA0kp9e3zf1oxR/1e2V8fI5wk2Bi+0FNAuf5rWpVta3Oin7i4/v8Ruiz/8oJV OV7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=iSH/9G2uxswFP6gkGEcQmnNa2z9g8VsdxM33bZx7bv0=; b=3CnoETJodNXmJ5hiqGTJ77NqwZgFOWBAWwoJ8DC+mCuXHeDHAdKwRHBt1lbMPsdN5P ybIyBpTZvCejXQ/i1cprOSHdHtC4swusHm7gxt9ZenctDuTkmftSxWqeX+bRNhN6MpHL FxQuuiWrp07u1Fs3QQnkyPKaGlr3wMu7ZZUe4wqD42QeA7RCeQOKTG5hi8OskpeUUUkC UGbezX2KSjdOnKdtUfIOLGQF6Vx+LyQJhtdkydje8yj4+i4LgVRz8CDColn8COgc9NXN nmV7WX7i1D/PMXs2zdvsQO2TmnJ3QF9k1grIhK5wl/6dZwekqCbjdPeb9l4woLS+q8bb pgfQ== X-Gm-Message-State: AOAM532hH5Q5VWZBKuyCe9yYjzdxFfa6sGJk5CyLr1T102DZOv6IhXfS lYCuvx+poE5mmk6JssgRKuAJGxJ/racAyGI88f0EbumZSdgbdWAbd6Kjvvw7VhCfpAakMWNVqXH f3V5Cih0vfAgvbxoIa5+Vq6+xm+HwicW5hv7Umyp0c1gp4mb2HvY8ln55epA7loE= X-Google-Smtp-Source: ABdhPJxTt4UcxOyc1/klJdlWYcGN66uMv0GTJlbqC3+LaRYmHWJSHpNI1PabOWRufiE9dGE3qCyvSL9pxALf0w== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90a:1b2e:: with SMTP id q43mr3347483pjq.56.1636425572028; Mon, 08 Nov 2021 18:39:32 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:01 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-13-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 12/17] KVM: selftests: aarch64: add tests for LEVEL_INFO in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add injection tests for the LEVEL_INFO ioctl (level-sensitive specific) into vgic_irq. Signed-off-by: Ricardo Koller --- tools/testing/selftests/kvm/aarch64/vgic_irq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index a20d225367a1..bc1b6fd684fc 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -60,6 +60,7 @@ typedef enum { KVM_INJECT_EDGE_IRQ_LINE = 1, KVM_SET_IRQ_LINE, KVM_SET_IRQ_LINE_HIGH, + KVM_SET_LEVEL_INFO_HIGH, } kvm_inject_cmd; struct kvm_inject_args { @@ -98,6 +99,7 @@ static struct kvm_inject_desc inject_edge_fns[] = { static struct kvm_inject_desc inject_level_fns[] = { /* sgi ppi spi */ { KVM_SET_IRQ_LINE_HIGH, false, true, true }, + { KVM_SET_LEVEL_INFO_HIGH, false, true, true }, { 0, }, }; @@ -406,6 +408,10 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, for (i = intid; i < intid + num; i++) kvm_arm_irq_line(vm, i, 1); break; + case KVM_SET_LEVEL_INFO_HIGH: + for (i = intid; i < intid + num; i++) + kvm_irq_set_level_info(gic_fd, i, 1); + break; default: break; } From patchwork Tue Nov 9 02:39:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Koller X-Patchwork-Id: 12609615 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E9B7C433F5 for ; Tue, 9 Nov 2021 02:39:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2AC85619E4 for ; Tue, 9 Nov 2021 02:39:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241902AbhKICmV (ORCPT ); Mon, 8 Nov 2021 21:42:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241774AbhKICmT (ORCPT ); Mon, 8 Nov 2021 21:42:19 -0500 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50D29C061764 for ; Mon, 8 Nov 2021 18:39:34 -0800 (PST) Received: by mail-pl1-x64a.google.com with SMTP id o8-20020a170902d4c800b001424abc88f3so3433724plg.2 for ; Mon, 08 Nov 2021 18:39:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=4fIWsaJ7AG87Eny4Oj2wlGi/WPege+GzmpcyzUfC/nA=; b=sdqIJ3tNj+06Vs15yWGRFfTW5dZ5joj8Aa4fZvsD8ZJrR1TY4RD/KU3ZhZDuX8zqXS wimZE18x7boDFaqI2o9fz/QPYw0q4wIeA2M9biLAx6U7CTFizQZXHO+EPT18un50aKVL vJVLjTJjbl4u0KKT9ezFMhwF0s9VsQIR6iKTrGnzAY56A0FERJrzPZBAaeiNvQ7my23/ Dofo88qFQnotiAM1LbZSwq0IPtpjDc2OoruW/txUm7GEGHc7XUnnG4RsNdEemQRQz4J9 OF24uosRg+LaLXfoIgQ2nqkLyWmFTP3BeuBBwOMKLU9XbmpM9YSjvS9Ifgxny8BCGo9p 7Ztw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=4fIWsaJ7AG87Eny4Oj2wlGi/WPege+GzmpcyzUfC/nA=; b=8E/tWRaGhTWASsmXiCxFc4QujBL0wzxx7SekjtsJBXQDbP7rTNi/d6bvX6wUL1nOtl tCsxNVAyRXY+c3DihMl0V3X6HqqAS+qcBvzKpQohk2aRoyoe6KDEw5f0H3gtmiTSdEgg 9Bs1cElK/FpeC+S944JEI2FmWdf9h0A4TzgGeAEZb3+04a3Y2HNoc6qDcSFYOd9Fn4b1 NHOeCU/9M9vEROYyZLe7oLUEmIOAsoG2TFI3vVAyrkcrwU7PMLk6AWGwLpGKo38Z5kv1 QNUop1Y5mfVkCXiIcaX7e+Jqwkn/pWALbXr6iTqEOzmk+2BrkPoqvLSOcBe7XouKIGcR 42PA== X-Gm-Message-State: AOAM530iuhpAHLWcNrhmpmGmQ2Ys7+GW3HVF5+VXVyZdWLKnZY06gwn4 fR6f82JXDL5v42TEPnjLO4VEirpuKI9algPNie7qACD9Ros8KiT0h2NqMmwYZHhky2onC+EjqQi Gv6oOOAHgqcMfYVe/ieSo1sBOYs17Yff3njEyayZMGGtnbjl2uetovPi9g7dMUoM= X-Google-Smtp-Source: ABdhPJxe7TUOGiysiHJWhoUKues6FGuvEwSAAtB2niN2S8OEli6XrUWSVccmzL0bWu42GNXILmsof4dgznU+5Q== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90b:4d8f:: with SMTP id oj15mr3295394pjb.127.1636425573621; Mon, 08 Nov 2021 18:39:33 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:02 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-14-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 13/17] KVM: selftests: aarch64: add test_inject_fail to vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add tests for failed injections to vgic_irq. This tests that KVM can handle bogus IRQ numbers. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 122 +++++++++++++++--- .../testing/selftests/kvm/lib/aarch64/vgic.c | 7 +- 2 files changed, 109 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index bc1b6fd684fc..9f1674b3a45c 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -68,21 +68,28 @@ struct kvm_inject_args { uint32_t first_intid; uint32_t num; int level; + bool expect_failure; }; /* Used on the guest side to perform the hypercall. */ static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, - uint32_t num, int level); + uint32_t num, int level, bool expect_failure); /* Used on the host side to get the hypercall info. */ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, struct kvm_inject_args *args); -#define KVM_INJECT(cmd, intid) \ - kvm_inject_call(cmd, intid, 1, -1 /* not used */) +#define _KVM_INJECT_MULTI(cmd, intid, num, expect_failure) \ + kvm_inject_call(cmd, intid, num, -1 /* not used */, expect_failure) #define KVM_INJECT_MULTI(cmd, intid, num) \ - kvm_inject_call(cmd, intid, num, -1 /* not used */) + _KVM_INJECT_MULTI(cmd, intid, num, false) + +#define _KVM_INJECT(cmd, intid, expect_failure) \ + _KVM_INJECT_MULTI(cmd, intid, 1, expect_failure) + +#define KVM_INJECT(cmd, intid) \ + _KVM_INJECT_MULTI(cmd, intid, 1, false) struct kvm_inject_desc { kvm_inject_cmd cmd; @@ -158,13 +165,14 @@ static void guest_irq_generic_handler(bool eoi_split, bool level_sensitive) } static void kvm_inject_call(kvm_inject_cmd cmd, uint32_t first_intid, - uint32_t num, int level) + uint32_t num, int level, bool expect_failure) { struct kvm_inject_args args = { .cmd = cmd, .first_intid = first_intid, .num = num, .level = level, + .expect_failure = expect_failure, }; GUEST_SYNC(&args); } @@ -206,7 +214,19 @@ static void reset_priorities(struct test_args *args) static void guest_set_irq_line(uint32_t intid, uint32_t level) { - kvm_inject_call(KVM_SET_IRQ_LINE, intid, 1, level); + kvm_inject_call(KVM_SET_IRQ_LINE, intid, 1, level, false); +} + +static void test_inject_fail(struct test_args *args, + uint32_t intid, kvm_inject_cmd cmd) +{ + reset_stats(); + + _KVM_INJECT(cmd, intid, true); + /* no IRQ to handle on entry */ + + GUEST_ASSERT_EQ(irq_handled, 0); + GUEST_ASSERT_IAR_EMPTY(); } static void guest_inject(struct test_args *args, @@ -330,6 +350,16 @@ static void test_injection(struct test_args *args, struct kvm_inject_desc *f) } } +static void test_injection_failure(struct test_args *args, + struct kvm_inject_desc *f) +{ + uint32_t bad_intid[] = { args->nr_irqs, 1020, 1024, 1120, 5120, ~0U, }; + int i; + + for (i = 0; i < ARRAY_SIZE(bad_intid); i++) + test_inject_fail(args, bad_intid[i], f->cmd); +} + static void test_preemption(struct test_args *args, struct kvm_inject_desc *f) { /* @@ -376,11 +406,61 @@ static void guest_code(struct test_args args) for_each_inject_fn(inject_fns, f) { test_injection(&args, f); test_preemption(&args, f); + test_injection_failure(&args, f); } GUEST_DONE(); } +static void kvm_irq_line_check(struct kvm_vm *vm, uint32_t intid, int level, + struct test_args *test_args, bool expect_failure) +{ + int ret; + + if (!expect_failure) { + kvm_arm_irq_line(vm, intid, level); + } else { + /* The interface doesn't allow larger intid's. */ + if (intid > KVM_ARM_IRQ_NUM_MASK) + return; + + ret = _kvm_arm_irq_line(vm, intid, level); + TEST_ASSERT(ret != 0 && errno == EINVAL, + "Bad intid %i did not cause KVM_IRQ_LINE " + "error: rc: %i errno: %i", intid, ret, errno); + } +} + +void kvm_irq_set_level_info_check(int gic_fd, uint32_t intid, int level, + bool expect_failure) +{ + if (!expect_failure) { + kvm_irq_set_level_info(gic_fd, intid, level); + } else { + int ret = _kvm_irq_set_level_info(gic_fd, intid, level); + /* + * The kernel silently fails for invalid SPIs and SGIs (which + * are not level-sensitive). It only checks for intid to not + * spill over 1U << 10 (the max reserved SPI). Also, callers + * are supposed to mask the intid with 0x3ff (1023). + */ + if (intid > VGIC_MAX_RESERVED) + TEST_ASSERT(ret != 0 && errno == EINVAL, + "Bad intid %i did not cause VGIC_GRP_LEVEL_INFO " + "error: rc: %i errno: %i", intid, ret, errno); + else + TEST_ASSERT(!ret, "KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO " + "for intid %i failed, rc: %i errno: %i", + intid, ret, errno); + } +} + +/* handles the valid case: intid=0xffffffff num=1 */ +#define for_each_intid(first, num, tmp, i) \ + for ((tmp) = (i) = (first); \ + (tmp) < (uint64_t)(first) + (uint64_t)(num); \ + (tmp)++, (i)++) + static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, struct kvm_inject_args *inject_args, struct test_args *test_args) @@ -389,28 +469,36 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, uint32_t intid = inject_args->first_intid; uint32_t num = inject_args->num; int level = inject_args->level; + bool expect_failure = inject_args->expect_failure; + uint64_t tmp; uint32_t i; - assert(intid < UINT_MAX - num); + /* handles the valid case: intid=0xffffffff num=1 */ + assert(intid < UINT_MAX - num || num == 1); switch (cmd) { case KVM_INJECT_EDGE_IRQ_LINE: - for (i = intid; i < intid + num; i++) - kvm_arm_irq_line(vm, i, 1); - for (i = intid; i < intid + num; i++) - kvm_arm_irq_line(vm, i, 0); + for_each_intid(intid, num, tmp, i) + kvm_irq_line_check(vm, i, 1, test_args, + expect_failure); + for_each_intid(intid, num, tmp, i) + kvm_irq_line_check(vm, i, 0, test_args, + expect_failure); break; case KVM_SET_IRQ_LINE: - for (i = intid; i < intid + num; i++) - kvm_arm_irq_line(vm, i, level); + for_each_intid(intid, num, tmp, i) + kvm_irq_line_check(vm, i, level, test_args, + expect_failure); break; case KVM_SET_IRQ_LINE_HIGH: - for (i = intid; i < intid + num; i++) - kvm_arm_irq_line(vm, i, 1); + for_each_intid(intid, num, tmp, i) + kvm_irq_line_check(vm, i, 1, test_args, + expect_failure); break; case KVM_SET_LEVEL_INFO_HIGH: - for (i = intid; i < intid + num; i++) - kvm_irq_set_level_info(gic_fd, i, 1); + for_each_intid(intid, num, tmp, i) + kvm_irq_set_level_info_check(gic_fd, i, 1, + expect_failure); break; default: break; diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c index 84206d7c92b4..b3a0fca0d780 100644 --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c @@ -110,12 +110,13 @@ int _kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level) { uint32_t irq = intid & KVM_ARM_IRQ_NUM_MASK; + TEST_ASSERT(!INTID_IS_SGI(intid), "KVM_IRQ_LINE's interface itself " + "doesn't allow injecting SGIs. There's no mask for it."); + if (INTID_IS_PPI(intid)) irq |= KVM_ARM_IRQ_TYPE_PPI << KVM_ARM_IRQ_TYPE_SHIFT; - else if (INTID_IS_SPI(intid)) - irq |= KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT; else - TEST_FAIL("KVM_IRQ_LINE can't be used with SGIs."); + irq |= KVM_ARM_IRQ_TYPE_SPI << KVM_ARM_IRQ_TYPE_SHIFT; return _kvm_irq_line(vm, irq, level); } From patchwork Tue Nov 9 02:39: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: 12609617 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 636F8C433EF for ; Tue, 9 Nov 2021 02:39:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D7D3619EC for ; Tue, 9 Nov 2021 02:39:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241969AbhKICmZ (ORCPT ); Mon, 8 Nov 2021 21:42:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38026 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241873AbhKICmV (ORCPT ); Mon, 8 Nov 2021 21:42:21 -0500 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 765E4C061764 for ; Mon, 8 Nov 2021 18:39:36 -0800 (PST) Received: by mail-pg1-x54a.google.com with SMTP id 76-20020a63054f000000b002c9284978aaso11274797pgf.10 for ; Mon, 08 Nov 2021 18:39:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=GES34y6vW0ebb/dfUgRINMRJKHYQGjmRo+EZqwaIueY=; b=jiXduLdnJkx6DErFWp2JDCOijv3TFXCxT3uZujtWXXxgyB0fFpmQtlBLiuqtzy3PDT YYZN5cL67RDOi6oDxCE5BZLUArXl0lyIA1BJYSiB6uqXr8qLJivYMihA1DPwK6IhlCFj +J1mOK6flPI7qR7JOEU/+m/RbmnFRTFFDSuG3SuCy3uCJTtbA4fv/EnFzgc6fr4NELZ3 PUgWnrLGaRB6RL5UYEyQ+0/8s+bjQboyZVYPM5iAlVNd1pCtNCUrhXOlNY0uzPqaqy1/ 429atQDcnFcqKzC7WEd12/4fFQ0CUhpuwLU1V0fY0WMojtWx26SgM3zxoSHncuJDP/r3 AVFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=GES34y6vW0ebb/dfUgRINMRJKHYQGjmRo+EZqwaIueY=; b=gdUTggG0xhTaDjC1JCg7huRDOaF5HMmR1UetpcA76FijolUY1FeTDGHrqsBp6ZNAIL 1lxQlqQtezogq7PNbBBj18+8bYG2Q4yT/g6ZrUF9fsMcBHzhRby8qUiOhzf24/FuKz1J G/BSzAvLp54uroKPvGWxtfhXAYCQYMdr4UTcxUk6rQ1WSsTriBxj8uC9XY+iuBeVbdQ7 DXPIPwY6+5MDrHFtDP0dSmM8gUIuwjMcrApdnq3dT4w+8CTro7F4A7UDE3/jq3piWMD/ 5anUA/J2UgPBRHMS4YSFUw194gJVLwKht/mHilmEEzgn5L+uNA0dCeuLbEIWN8jtUv8t jhlg== X-Gm-Message-State: AOAM533VosIG8hoA6SIOwVOv+ZwDFy5uyQrLzsca19b9Z23oR/f40JcG SPoduXl2REVEKeIkbCCLZE/wc6jfUCav4QoOlqsX41bYE0ZxLSDGsQfp2NIIQynbSnjabZDf7zs 1aUiWf+YIXtYFR6C+fGZA5Q6Po4PHVveECQBGpctSAWbd2dIkFZyO00Fkm0vII8k= X-Google-Smtp-Source: ABdhPJzO1D1+Dk2URw44WZn2b3SSBgPjATtGTsr+/7avX/ccU6voQidUrVDPgjRDV2e/RzeBE1FF4OFi9Upaqw== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:90a:284f:: with SMTP id p15mr137518pjf.1.1636425575183; Mon, 08 Nov 2021 18:39:35 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:03 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-15-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 14/17] KVM: selftests: add IRQ GSI routing library functions From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add an architecture independent wrapper function for creating and writing IRQ GSI routing tables. Also add a function to add irqchip entries. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/include/kvm_util.h | 8 +++ tools/testing/selftests/kvm/lib/kvm_util.c | 51 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index c6831fd8aea7..26c0722d7f77 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -251,6 +251,14 @@ int _vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, int vcpu_access_device_attr(struct kvm_vm *vm, uint32_t vcpuid, uint32_t group, uint64_t attr, void *val, bool write); +#define KVM_MAX_IRQ_ROUTES 4096 + +struct kvm_irq_routing *kvm_gsi_routing_create(void); +void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing, + uint32_t gsi, uint32_t pin); +int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); +void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing); + const char *exit_reason_str(unsigned int exit_reason); void virt_pgd_alloc(struct kvm_vm *vm); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 7d9cb8358702..2a38d717bc67 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2099,6 +2099,57 @@ void kvm_irq_line(struct kvm_vm *vm, uint32_t irq, int level) TEST_ASSERT(ret >= 0, "KVM_IRQ_LINE failed, rc: %i errno: %i", ret, errno); } +struct kvm_irq_routing *kvm_gsi_routing_create(void) +{ + struct kvm_irq_routing *routing; + size_t size; + + size = sizeof(struct kvm_irq_routing); + /* Allocate space for the max number of entries: this wastes 196 KBs. */ + size += KVM_MAX_IRQ_ROUTES * sizeof(struct kvm_irq_routing_entry); + routing = calloc(1, size); + assert(routing); + + return routing; +} + +void kvm_gsi_routing_irqchip_add(struct kvm_irq_routing *routing, + uint32_t gsi, uint32_t pin) +{ + int i; + + assert(routing); + assert(routing->nr < KVM_MAX_IRQ_ROUTES); + + i = routing->nr; + routing->entries[i].gsi = gsi; + routing->entries[i].type = KVM_IRQ_ROUTING_IRQCHIP; + routing->entries[i].flags = 0; + routing->entries[i].u.irqchip.irqchip = 0; + routing->entries[i].u.irqchip.pin = pin; + routing->nr++; +} + +int _kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing) +{ + int ret; + + assert(routing); + ret = ioctl(vm_get_fd(vm), KVM_SET_GSI_ROUTING, routing); + free(routing); + + return ret; +} + +void kvm_gsi_routing_write(struct kvm_vm *vm, struct kvm_irq_routing *routing) +{ + int ret; + + ret = _kvm_gsi_routing_write(vm, routing); + TEST_ASSERT(ret == 0, "KVM_SET_GSI_ROUTING failed, rc: %i errno: %i", + ret, errno); +} + /* * VM Dump * From patchwork Tue Nov 9 02:39: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: 12609619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B40EC433FE for ; Tue, 9 Nov 2021 02:39:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61B5E619A6 for ; Tue, 9 Nov 2021 02:39:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241907AbhKICm0 (ORCPT ); Mon, 8 Nov 2021 21:42:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241929AbhKICmX (ORCPT ); Mon, 8 Nov 2021 21:42:23 -0500 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 A8F0EC0613B9 for ; Mon, 8 Nov 2021 18:39:37 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id y124-20020a623282000000b0047a09271e49so11969315pfy.16 for ; Mon, 08 Nov 2021 18:39:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=igtNCs/EdQGdJFkd8S66UsbWC4E3b2XpCSh4teAekRY=; b=i0neKE5eIA9O5ihA63SgrJVllahwMqAEv84n9PQafp4I0majIgaxlX1lRfZvQ+2FoR QyVP4CWlFmpXrVz0MJbXjL+XiLNgeESeqzmx25UAylf/rQR6VOCcPlG89XgloRKpXKtR Ru0D4STMeW1qfxMv+sq6DYdEE/9zM0l0ja13ZOpwq4gzLIqVZQRYMy6ZOjod6u8KQeQw nGhUkO9jziaFFKhjDky63H7nCUNFnm/S9elbn0fZO3bTV/z2TZSpuXhR5j5sMAPmwsyX x9sB55tWOsIa3Oyz/YBp5VmY2dI3STwUJk0HjAfCVXw8jPxSccxoR0sxxSyJc2SnHxHC H+kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=igtNCs/EdQGdJFkd8S66UsbWC4E3b2XpCSh4teAekRY=; b=Go+nidFgqjexfMaxHB2lDT0tC16AQzYwYbyH7kANZkvn1m5kMZyOO69+6Q7xWch/7/ yLv2aa/y/2m/Vth3zuQJ3d2KngnPQiArvgNlHq4+LOGePwonR19+yOokmkaUEuDntA5g A8NDsobJSEGS6NZlO2tfZCBZpuYFbgi1QY7quQ5nQ4xybVY23txXVNxG8CPQ669pKija 5DqwvecTpVQgP2q7xxF1Qvw6QSQ80k6XlOikOkZTLq6ecwPkIErW3h5jGlXj/01A6VJK /+kivfMmGUwWrhNccml0yz5mLMB2rScG+O8z292dZQB8e2S+VQhdWuqd+yyCFccctmVK LS8g== X-Gm-Message-State: AOAM532i4ZNns8Lltip/IYJbNqB1v0quhFsnpaHROzHelbtYEwZRlXUq xrGT1uGylgS476ou+KKSIrxGEIV++jw2c4UO3Z7VM4fkth4goM26ry3C24Gblg+Mdt1y0ocrpg4 c7FJHpsVMMB9EkUj2V/4RJqfJb6mBOkIpZEyfu7fn/Ue4LXS2Ttpw+wP1nNsOsIQ= X-Google-Smtp-Source: ABdhPJwpIp4nej4Ka3+5nbnKShwE7lHQyfASuzjkFE1r2avt/z5DkQiTZ2DJ4QZBJfdyPR07SFtRnf1BQiFExA== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:903:1207:b0:13d:b9b1:ead7 with SMTP id l7-20020a170903120700b0013db9b1ead7mr3940753plh.63.1636425577086; Mon, 08 Nov 2021 18:39:37 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:04 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-16-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 15/17] KVM: selftests: aarch64: add tests for IRQFD in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add injection tests for the KVM_IRQFD ioctl into vgic_irq. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 101 +++++++++++++++++- .../selftests/kvm/include/aarch64/vgic.h | 2 + 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index 9f1674b3a45c..121113f24ed3 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "processor.h" @@ -31,6 +32,8 @@ struct test_args { uint32_t nr_irqs; /* number of KVM supported IRQs. */ bool eoi_split; /* 1 is eoir+dir, 0 is eoir only */ bool level_sensitive; /* 1 is level, 0 is edge */ + int kvm_max_routes; /* output of KVM_CAP_IRQ_ROUTING */ + bool kvm_supports_irqfd; /* output of KVM_CAP_IRQFD */ }; /* @@ -61,6 +64,7 @@ typedef enum { KVM_SET_IRQ_LINE, KVM_SET_IRQ_LINE_HIGH, KVM_SET_LEVEL_INFO_HIGH, + KVM_INJECT_IRQFD, } kvm_inject_cmd; struct kvm_inject_args { @@ -100,6 +104,7 @@ struct kvm_inject_desc { static struct kvm_inject_desc inject_edge_fns[] = { /* sgi ppi spi */ { KVM_INJECT_EDGE_IRQ_LINE, false, false, true }, + { KVM_INJECT_IRQFD, false, false, true }, { 0, }, }; @@ -107,12 +112,17 @@ static struct kvm_inject_desc inject_level_fns[] = { /* sgi ppi spi */ { KVM_SET_IRQ_LINE_HIGH, false, true, true }, { KVM_SET_LEVEL_INFO_HIGH, false, true, true }, + { KVM_INJECT_IRQFD, false, false, true }, { 0, }, }; #define for_each_inject_fn(t, f) \ for ((f) = (t); (f)->cmd; (f)++) +#define for_each_supported_inject_fn(args, t, f) \ + for_each_inject_fn(t, f) \ + if ((args)->kvm_supports_irqfd || (f)->cmd != KVM_INJECT_IRQFD) + /* Shared between the guest main thread and the IRQ handlers. */ volatile uint64_t irq_handled; volatile uint32_t irqnr_received[MAX_SPI + 1]; @@ -403,7 +413,7 @@ static void guest_code(struct test_args args) local_irq_enable(); /* Start the tests. */ - for_each_inject_fn(inject_fns, f) { + for_each_supported_inject_fn(&args, inject_fns, f) { test_injection(&args, f); test_preemption(&args, f); test_injection_failure(&args, f); @@ -455,6 +465,88 @@ void kvm_irq_set_level_info_check(int gic_fd, uint32_t intid, int level, } } +static void kvm_set_gsi_routing_irqchip_check(struct kvm_vm *vm, + uint32_t intid, uint32_t num, uint32_t kvm_max_routes, + bool expect_failure) +{ + struct kvm_irq_routing *routing; + int ret; + uint64_t i; + + assert(num <= kvm_max_routes && kvm_max_routes <= KVM_MAX_IRQ_ROUTES); + + routing = kvm_gsi_routing_create(); + for (i = intid; i < (uint64_t)intid + num; i++) + kvm_gsi_routing_irqchip_add(routing, i - MIN_SPI, i - MIN_SPI); + + if (!expect_failure) { + kvm_gsi_routing_write(vm, routing); + } else { + ret = _kvm_gsi_routing_write(vm, routing); + /* The kernel only checks for KVM_IRQCHIP_NUM_PINS. */ + if (intid >= KVM_IRQCHIP_NUM_PINS) + TEST_ASSERT(ret != 0 && errno == EINVAL, + "Bad intid %u did not cause KVM_SET_GSI_ROUTING " + "error: rc: %i errno: %i", intid, ret, errno); + else + TEST_ASSERT(ret == 0, "KVM_SET_GSI_ROUTING " + "for intid %i failed, rc: %i errno: %i", + intid, ret, errno); + } +} + +static void kvm_routing_and_irqfd_check(struct kvm_vm *vm, + uint32_t intid, uint32_t num, uint32_t kvm_max_routes, + bool expect_failure) +{ + int fd[MAX_SPI]; + uint64_t val; + int ret, f; + uint64_t i; + + /* + * There is no way to try injecting an SGI or PPI as the interface + * starts counting from the first SPI (above the private ones), so just + * exit. + */ + if (INTID_IS_SGI(intid) || INTID_IS_PPI(intid)) + return; + + kvm_set_gsi_routing_irqchip_check(vm, intid, num, + kvm_max_routes, expect_failure); + + /* + * If expect_failure, then just to inject anyway. These + * will silently fail. And in any case, the guest will check + * that no actual interrupt was injected for those cases. + */ + + for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { + fd[f] = eventfd(0, 0); + TEST_ASSERT(fd[f] != -1, + "eventfd failed, errno: %i\n", errno); + } + + for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { + struct kvm_irqfd irqfd = { + .fd = fd[f], + .gsi = i - MIN_SPI, + }; + assert(i <= (uint64_t)UINT_MAX); + vm_ioctl(vm, KVM_IRQFD, &irqfd); + } + + for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) { + val = 1; + ret = write(fd[f], &val, sizeof(uint64_t)); + TEST_ASSERT(ret == sizeof(uint64_t), + "Write to KVM_IRQFD failed with ret: %d\n", ret); + } + + for (f = 0, i = intid; i < (uint64_t)intid + num; i++, f++) + close(fd[f]); +} + /* handles the valid case: intid=0xffffffff num=1 */ #define for_each_intid(first, num, tmp, i) \ for ((tmp) = (i) = (first); \ @@ -500,6 +592,11 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, kvm_irq_set_level_info_check(gic_fd, i, 1, expect_failure); break; + case KVM_INJECT_IRQFD: + kvm_routing_and_irqfd_check(vm, intid, num, + test_args->kvm_max_routes, + expect_failure); + break; default: break; } @@ -534,6 +631,8 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split) .nr_irqs = nr_irqs, .level_sensitive = level_sensitive, .eoi_split = eoi_split, + .kvm_max_routes = kvm_check_cap(KVM_CAP_IRQ_ROUTING), + .kvm_supports_irqfd = kvm_check_cap(KVM_CAP_IRQFD), }; print_args(&args); diff --git a/tools/testing/selftests/kvm/include/aarch64/vgic.h b/tools/testing/selftests/kvm/include/aarch64/vgic.h index ce6f0383c1a1..4442081221a0 100644 --- a/tools/testing/selftests/kvm/include/aarch64/vgic.h +++ b/tools/testing/selftests/kvm/include/aarch64/vgic.h @@ -29,4 +29,6 @@ int _kvm_arm_irq_line(struct kvm_vm *vm, uint32_t intid, int level); void kvm_irq_write_ispendr(int gic_fd, uint32_t intid, uint32_t vcpu); void kvm_irq_write_isactiver(int gic_fd, uint32_t intid, uint32_t vcpu); +#define KVM_IRQCHIP_NUM_PINS (1020 - 32) + #endif // SELFTEST_KVM_VGIC_H From patchwork Tue Nov 9 02:39: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: 12609621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A669AC433FE for ; Tue, 9 Nov 2021 02:39:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 90759619E5 for ; Tue, 9 Nov 2021 02:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242046AbhKICmd (ORCPT ); Mon, 8 Nov 2021 21:42:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38062 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241873AbhKICmZ (ORCPT ); Mon, 8 Nov 2021 21:42:25 -0500 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E88BC061764 for ; Mon, 8 Nov 2021 18:39:39 -0800 (PST) Received: by mail-pg1-x549.google.com with SMTP id e4-20020a630f04000000b002cc40fe16afso11241712pgl.23 for ; Mon, 08 Nov 2021 18:39:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=tc3mXVzzOaZBy5gyuY36RG3hrmBxESsxJH6cjzwnYCE=; b=Re6hB7wRoT18fAcpM30azZmr5LuzK6wqyf/A8iUeb0FcMAeRijXmJNCamHrNbyVJYV sa2cJFJkbLzmyswtvwuSPlxXVH3CkpN9Nn6mxLs+UVXzoDgnQGLMxFV0kYA5RrDvBEON 9yH2SI589qCICvAD68c8bWJZ0dftj7oYaul1wnYvGoGu9ylzuZzZnb5OBxJJm1JKmI/F dJ/98P6tXrZmYr+cNwokFbq/PitIVz6TVdDoR2LjkxFKB8graOPS8Ri559A05evEmb1x n/2RQ5x6zo/jGhyllBtP/5qqdC0SeY5JCcUCmsp7ifL+6z8bMWQARIqeTF4H2/ooQrSF 7ujA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=tc3mXVzzOaZBy5gyuY36RG3hrmBxESsxJH6cjzwnYCE=; b=VeBRQkNiVqMgpogb9S5njwIo0eWrbMJzPnlDapvq2OSSzLICtukVrhCBu5pO+OP8QG AdBjMeBnUw77HRPoMoxXZ+cEZFFgWj2M7KzRUvOAK9S6zTTN9QVkTLJABSNO8WzpqWnB fDEgMVUxBC6o5eSfzjRQ/Shq2As0fEui038aKeIDc7i311WQvoAuvO9s8iXtmpizo9zo laqg1cL6dHZvJ1EbIRulLZK6vx4ob41HCKLpWOQ7TPfM2srMOJaQaPslo0Ovzt8nEaH9 is2b1kGBcZLRoQFAJNE4W6zbCD8/r9U5AtT3KlY+gt28rIi34L6+tW3Vhc+fSIkb2sJi cIYQ== X-Gm-Message-State: AOAM533cfs+CThVJsn/5PMegaeDwfzOlgvccHhg6VaoBaz8wD/DlawkN WE3J/n8SxEWVmYvDUNlgx3styLin7VgUlIw6nfokn/ZuEDkVIAsWMDKmTLINTVZ3F+I0QmIkUDx yw939nI+MMADLCNH02ZqDxLyXo81065LiB91E9nQZZ+m/nqJwykoypx5q9jKzs8E= X-Google-Smtp-Source: ABdhPJyPSCCkl/K5UVGKkEu9Pa4VFG9SOYr7MwUgakcjaRqD+5d0aaPnebxqZaIiLnYnhcP9ybbQCof1iuzpkg== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:7608:b0:141:9a53:ceff with SMTP id k8-20020a170902760800b001419a53ceffmr3722147pll.78.1636425578745; Mon, 08 Nov 2021 18:39:38 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:05 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-17-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 16/17] KVM: selftests: aarch64: add ISPENDR write tests in vgic_irq From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add injection tests that use writing into the ISPENDR register (to mark IRQs as pending). This is typically used by migration code. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index 121113f24ed3..ab39f0bf18e7 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -65,6 +65,7 @@ typedef enum { KVM_SET_IRQ_LINE_HIGH, KVM_SET_LEVEL_INFO_HIGH, KVM_INJECT_IRQFD, + KVM_WRITE_ISPENDR, } kvm_inject_cmd; struct kvm_inject_args { @@ -105,6 +106,7 @@ static struct kvm_inject_desc inject_edge_fns[] = { /* sgi ppi spi */ { KVM_INJECT_EDGE_IRQ_LINE, false, false, true }, { KVM_INJECT_IRQFD, false, false, true }, + { KVM_WRITE_ISPENDR, true, false, true }, { 0, }, }; @@ -113,6 +115,7 @@ static struct kvm_inject_desc inject_level_fns[] = { { KVM_SET_IRQ_LINE_HIGH, false, true, true }, { KVM_SET_LEVEL_INFO_HIGH, false, true, true }, { KVM_INJECT_IRQFD, false, false, true }, + { KVM_WRITE_ISPENDR, false, true, true }, { 0, }, }; @@ -495,6 +498,20 @@ static void kvm_set_gsi_routing_irqchip_check(struct kvm_vm *vm, } } +static void kvm_irq_write_ispendr_check(int gic_fd, uint32_t intid, + uint32_t vcpu, bool expect_failure) +{ + /* + * Ignore this when expecting failure as invalid intids will lead to + * either trying to inject SGIs when we configured the test to be + * level_sensitive (or the reverse), or inject large intids which + * will lead to writing above the ISPENDR register space (and we + * don't want to do that either). + */ + if (!expect_failure) + kvm_irq_write_ispendr(gic_fd, intid, vcpu); +} + static void kvm_routing_and_irqfd_check(struct kvm_vm *vm, uint32_t intid, uint32_t num, uint32_t kvm_max_routes, bool expect_failure) @@ -597,6 +614,11 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, test_args->kvm_max_routes, expect_failure); break; + case KVM_WRITE_ISPENDR: + for (i = intid; i < intid + num; i++) + kvm_irq_write_ispendr_check(gic_fd, i, + VCPU_ID, expect_failure); + break; default: break; } From patchwork Tue Nov 9 02:39: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: 12609623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9200FC433EF for ; Tue, 9 Nov 2021 02:39:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 81CAC619E4 for ; Tue, 9 Nov 2021 02:39:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241894AbhKICmf (ORCPT ); Mon, 8 Nov 2021 21:42:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241917AbhKICm0 (ORCPT ); Mon, 8 Nov 2021 21:42:26 -0500 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 F07F8C061767 for ; Mon, 8 Nov 2021 18:39:40 -0800 (PST) Received: by mail-pf1-x449.google.com with SMTP id x25-20020aa79199000000b0044caf0d1ba8so12003143pfa.1 for ; Mon, 08 Nov 2021 18:39:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=PPiN1OStZtyVFCjdaIWEwxJI+HtnmXRJCjCg0WeY/1o=; b=OxMHCCrLIoOcCMO/e5i3qk9CbDTPcyfH/A0Qr9+1rMkft67CvoCbmVGS73fctt+EO5 NqvDBRhCHVAGsjWn5IBooSf2P8XSrqLQAPuBh5nWiACSD7eGaw/fA0Upe6wDptH9zDy9 eDTRtvDOCzWsKdo7N+KbAyOBihzFY12OSkL2pZOHYky9xGaNC4svekA/tbK6Sf0iuSym qVuX3POy/yYEBSX6BsVnctG2MlD2vtKB08buXcUsSmQgvJ/RD/ecv7rqlgUOwwjf7h9D UyCo9QxmWzIDZ5/7rsn8Rjzfge40e6w4oGUqEHUXD9hIE8sOYbAWzDCnipaiI6sgAO53 b5zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=PPiN1OStZtyVFCjdaIWEwxJI+HtnmXRJCjCg0WeY/1o=; b=EjJ10G8wBfHcbVsFh87cJa+U7zRz19woyqB1iU/+N1VK+Hn0yO2mTm+dK/pXkd0dmz qSqk8rGfsjEW7gGxKa4FiPSEm3tqAwUVuPnVKCOaG2ncF7up+ugpM9J96kemrhsO6/Lp GFAgXSQ4s9cR/FFZeRDrtGsMGhFoyJh5PmkKpXXX1/zsaTLIwyq9T6PKMcet6UJzVf9i F+VGqTvzSG+XlL1RXGC4+7LrkkDgHxFeAhIpYKhhDaGdj8ePuisC8wL0Y2Ru4Ewaqw7x x45sHqGq0JJyJB69659yzj8aTlY5gJGQpj1ddwzovbhpos6i+k3dNmVy5YtR26IppA9f Yvfg== X-Gm-Message-State: AOAM533yuSup/sAgdSGAFVPlCGjtjpNQXXwedDCrYXbQgOVrQavrA8xI J1p/IHakGiv7sQSgGLTY545xVxy6B30CwCGpuDYS771R75NJfxEKbWLszp/b4QRXFvfLVYZwwgX +sogBvviPqCgcMVLZutlt5ZeHYb8c1KAeuWgEG5LkupDZkdu3rWY4CIgTja+dXfc= X-Google-Smtp-Source: ABdhPJxU+zWdcLp8dVxfcgRk+DuxHI2NjXI/Ir2OWJNuLQgheWLYUiaRCPVy7IyeFg4h4yIqHdXiJWMiaj63TQ== X-Received: from ricarkol2.c.googlers.com ([fda3:e722:ac3:cc00:24:72f4:c0a8:62fe]) (user=ricarkol job=sendgmr) by 2002:a17:902:ced0:b0:142:189a:4284 with SMTP id d16-20020a170902ced000b00142189a4284mr3987840plg.79.1636425580412; Mon, 08 Nov 2021 18:39:40 -0800 (PST) Date: Mon, 8 Nov 2021 18:39:06 -0800 In-Reply-To: <20211109023906.1091208-1-ricarkol@google.com> Message-Id: <20211109023906.1091208-18-ricarkol@google.com> Mime-Version: 1.0 References: <20211109023906.1091208-1-ricarkol@google.com> X-Mailer: git-send-email 2.34.0.rc0.344.g81b53c2807-goog Subject: [PATCH 17/17] KVM: selftests: aarch64: add test for restoring active IRQs From: Ricardo Koller To: kvm@vger.kernel.org, maz@kernel.org, kvmarm@lists.cs.columbia.edu, drjones@redhat.com, eric.auger@redhat.com, alexandru.elisei@arm.com Cc: Paolo Bonzini , oupton@google.com, james.morse@arm.com, suzuki.poulose@arm.com, shuah@kernel.org, jingzhangos@google.com, pshier@google.com, rananta@google.com, reijiw@google.com, Ricardo Koller Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add a test that restores multiple IRQs in active state, it does it by writing into ISACTIVER from the guest and using KVM ioctls. This test tries to emulate what would happen during a live migration: restore active IRQs. Signed-off-by: Ricardo Koller --- .../testing/selftests/kvm/aarch64/vgic_irq.c | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c index ab39f0bf18e7..e6c7d7f8fbd1 100644 --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c @@ -66,6 +66,7 @@ typedef enum { KVM_SET_LEVEL_INFO_HIGH, KVM_INJECT_IRQFD, KVM_WRITE_ISPENDR, + KVM_WRITE_ISACTIVER, } kvm_inject_cmd; struct kvm_inject_args { @@ -96,6 +97,9 @@ static void kvm_inject_get_call(struct kvm_vm *vm, struct ucall *uc, #define KVM_INJECT(cmd, intid) \ _KVM_INJECT_MULTI(cmd, intid, 1, false) +#define KVM_ACTIVATE(cmd, intid) \ + kvm_inject_call(cmd, intid, 1, 1, false); + struct kvm_inject_desc { kvm_inject_cmd cmd; /* can inject PPIs, PPIs, and/or SPIs. */ @@ -119,6 +123,12 @@ static struct kvm_inject_desc inject_level_fns[] = { { 0, }, }; +static struct kvm_inject_desc set_active_fns[] = { + /* sgi ppi spi */ + { KVM_WRITE_ISACTIVER, true, true, true }, + { 0, }, +}; + #define for_each_inject_fn(t, f) \ for ((f) = (t); (f)->cmd; (f)++) @@ -126,6 +136,9 @@ static struct kvm_inject_desc inject_level_fns[] = { for_each_inject_fn(t, f) \ if ((args)->kvm_supports_irqfd || (f)->cmd != KVM_INJECT_IRQFD) +#define for_each_supported_activate_fn(args, t, f) \ + for_each_supported_inject_fn((args), (t), (f)) + /* Shared between the guest main thread and the IRQ handlers. */ volatile uint64_t irq_handled; volatile uint32_t irqnr_received[MAX_SPI + 1]; @@ -147,6 +160,12 @@ static uint64_t gic_read_ap1r0(void) return reg; } +static void gic_write_ap1r0(uint64_t val) +{ + write_sysreg_s(val, SYS_ICV_AP1R0_EL1); + isb(); +} + static void guest_set_irq_line(uint32_t intid, uint32_t level); static void guest_irq_generic_handler(bool eoi_split, bool level_sensitive) @@ -274,6 +293,55 @@ static void guest_inject(struct test_args *args, reset_priorities(args); } +/* + * Restore the active state of multiple concurrent IRQs (given by + * concurrent_irqs). This does what a live-migration would do on the + * destination side assuming there are some active IRQs that were not + * deactivated yet. + */ +static void guest_restore_active(struct test_args *args, + uint32_t first_intid, uint32_t num, + kvm_inject_cmd cmd) +{ + uint32_t prio, intid, ap1r; + int i; + + /* Set the priorities of the first (KVM_NUM_PRIOS - 1) IRQs + * in descending order, so intid+1 can preempt intid. + */ + for (i = 0, prio = (num - 1) * 8; i < num; i++, prio -= 8) { + GUEST_ASSERT(prio >= 0); + intid = i + first_intid; + gic_set_priority(intid, prio); + } + + /* In a real migration, KVM would restore all GIC state before running + * guest code. + */ + for (i = 0; i < num; i++) { + intid = i + first_intid; + KVM_ACTIVATE(cmd, intid); + ap1r = gic_read_ap1r0(); + ap1r |= 1U << i; + gic_write_ap1r0(ap1r); + } + + /* This is where the "migration" would occur. */ + + /* finish handling the IRQs starting with the highest priority one. */ + for (i = 0; i < num; i++) { + intid = num - i - 1 + first_intid; + gic_set_eoi(intid); + if (args->eoi_split) + gic_set_dir(intid); + } + + for (i = 0; i < num; i++) + GUEST_ASSERT(!gic_irq_get_active(i + first_intid)); + GUEST_ASSERT_EQ(gic_read_ap1r0(), 0); + GUEST_ASSERT_IAR_EMPTY(); +} + /* * Polls the IAR until it's not a spurious interrupt. * @@ -391,6 +459,19 @@ static void test_preemption(struct test_args *args, struct kvm_inject_desc *f) test_inject_preemption(args, MIN_SPI, 4, f->cmd); } +static void test_restore_active(struct test_args *args, struct kvm_inject_desc *f) +{ + /* Test up to 4 active IRQs. Same reason as in test_preemption. */ + if (f->sgi) + guest_restore_active(args, MIN_SGI, 4, f->cmd); + + if (f->ppi) + guest_restore_active(args, MIN_PPI, 4, f->cmd); + + if (f->spi) + guest_restore_active(args, MIN_SPI, 4, f->cmd); +} + static void guest_code(struct test_args args) { uint32_t i, nr_irqs = args.nr_irqs; @@ -422,6 +503,12 @@ static void guest_code(struct test_args args) test_injection_failure(&args, f); } + /* Restore the active state of IRQs. This would happen when live + * migrating IRQs in the middle of being handled. + */ + for_each_supported_activate_fn(&args, set_active_fns, f) + test_restore_active(&args, f); + GUEST_DONE(); } @@ -619,6 +706,10 @@ static void run_guest_cmd(struct kvm_vm *vm, int gic_fd, kvm_irq_write_ispendr_check(gic_fd, i, VCPU_ID, expect_failure); break; + case KVM_WRITE_ISACTIVER: + for (i = intid; i < intid + num; i++) + kvm_irq_write_isactiver(gic_fd, i, VCPU_ID); + break; default: break; }