From patchwork Wed Nov 17 06:43:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reiji Watanabe X-Patchwork-Id: 12692853 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 4A55DC433EF for ; Wed, 17 Nov 2021 07:14:34 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0F85461A53 for ; Wed, 17 Nov 2021 07:14:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0F85461A53 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=vj6lpbYqrB3we9/rtYs1xDXSoac4hiVJOZNnWX9c0CE=; b=mDJv4W0ND8VpKZ7F67HXOWZIkL gpyjx1bCi+2cjvGxhvcIT7S4eK1ySC4pbjs8UQhmYKa6oFRdon9LzQ9bEq5TZdKD58ybpLRh/9vNU J6YtW5gFDTfyFg2UDkop0YL8+yaGqjM5HRW9ThSvG166JeVddZtFUFkG9MBEW8CfkEhOIGbJlMg6d TB3El6hYYCB325QD9E6MiPv4w5lcNnmV54C4rQvhSl3pyHEV3JCq6q2LgRX0fE/BRK0zyil8uH/+X qRTcqmXqAUOjHMNSUUHiUCcO8L6LAN7AxeIOOrIeaFcG2A4QQuOZWY1Q85HfLdAzh4aaEggZHSacA jMHlnBiw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mnF7S-003geC-SW; Wed, 17 Nov 2021 07:12:35 +0000 Received: from mail-pf1-x449.google.com ([2607:f8b0:4864:20::449]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mnEpO-003a3s-NC for linux-arm-kernel@lists.infradead.org; Wed, 17 Nov 2021 06:53:56 +0000 Received: by mail-pf1-x449.google.com with SMTP id y68-20020a627d47000000b004a2f6a1551cso1084757pfc.23 for ; Tue, 16 Nov 2021 22:53:53 -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=3Vy8zl0uiB6BzrVyosP76h+gx7fVBOmrAidLKwyOmLo=; b=SIFfTVfI7I8A9xtfgW2SGwAAgVjhFtCYzxi+nqRkzYADw/h3e55zX8dv0tcR7U3gTs Ow0HGNvpz/NuJG85fy363/AcS51o/aycC/kCv5uCjNhS+RCTNdAFQi4+DcDeTOnDeDse FVkEWvlwCHnfDvOvPIJ9ghlPfoOQgt8kKi10mbK55MgoCJkbF1IJEjpJu1oblfYzNLKq y4xT6lWYpL+xwM+iKPJwn2wFgMnVAK5Or854NPyaNECj9/og+mfPKEOLl7iIRm4Lmngr PItBcWboqdv21plvaPRpZkKCuZVq0DXHslVP9GpedQEfAciDbpFEfcddLsx2m9IGBW55 wq+w== 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=3Vy8zl0uiB6BzrVyosP76h+gx7fVBOmrAidLKwyOmLo=; b=NzCD/YcmYuv+jdQaY2TnKzCRgQ8aVvaFV5x4uU/Vllmw2i20AMbm9rZA1NeMgBjlh9 zqzliR7Y8XZodR93bpZJV314UoR/4nxYRDLVOQPC1tmuyQFzDE2xFZqjIMne33ii3XRW N7BGvjiQ5NLkXDnv7hpEIUPaYJRLwAuE+W1Ax7dJxVMVk+07Z9Qhrq1y27STWufR+BN8 Gc6ow6bU7DPcWFrzOndSMENaPVa4z2e/yjtPb7raSErPtb1Luu5WjgfrMo/0KskWb3yE q3eEBra9fEJsPgy5SXfWK01k7woScGppW1PKbNwIbOwkubbFnED/ElCdG12OTirxmG4A r6Gw== X-Gm-Message-State: AOAM533vzMr9EPuaCUdxts/1f0EfuEkv3WZ6Ip6zpddrOrHPC3J7aYct fuDfWAnXDLHMkUJxUFpJtlN0G3+usis= X-Google-Smtp-Source: ABdhPJyuYg+X9kpMVUPN5OoZNv12tw8vlVgjnQ4xCZ/tC4KYbUa1SUFiMJwvsngrbAH2RAUicLELQrXc63o= X-Received: from reiji-vws-sp.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:3d59]) (user=reijiw job=sendgmr) by 2002:a17:902:ed89:b0:141:f601:d6a with SMTP id e9-20020a170902ed8900b00141f6010d6amr52839367plj.77.1637132033292; Tue, 16 Nov 2021 22:53:53 -0800 (PST) Date: Tue, 16 Nov 2021 22:43:58 -0800 In-Reply-To: <20211117064359.2362060-1-reijiw@google.com> Message-Id: <20211117064359.2362060-29-reijiw@google.com> Mime-Version: 1.0 References: <20211117064359.2362060-1-reijiw@google.com> X-Mailer: git-send-email 2.34.0.rc1.387.gb447b232ab-goog Subject: [RFC PATCH v3 28/29] KVM: arm64: Add kunit test for trap initialization From: Reiji Watanabe To: Marc Zyngier , kvmarm@lists.cs.columbia.edu Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, James Morse , Alexandru Elisei , Suzuki K Poulose , Paolo Bonzini , Will Deacon , Andrew Jones , Peng Liang , Peter Shier , Ricardo Koller , Oliver Upton , Jing Zhang , Raghavendra Rao Anata , Reiji Watanabe X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211116_225354_825370_CDFB9907 X-CRM114-Status: GOOD ( 14.18 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add KUnit tests for functions that initialize traps. Signed-off-by: Reiji Watanabe --- arch/arm64/kvm/sys_regs_test.c | 238 +++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/arch/arm64/kvm/sys_regs_test.c b/arch/arm64/kvm/sys_regs_test.c index 8d27c7c361fb..f73b207be4ee 100644 --- a/arch/arm64/kvm/sys_regs_test.c +++ b/arch/arm64/kvm/sys_regs_test.c @@ -844,6 +844,241 @@ static void validate_mvfr1_el1_test(struct kunit *test) test_kvm_vcpu_fini(test, vcpu); } +static void feature_trap_activate_test(struct kunit *test) +{ + struct kvm_vcpu *vcpu; + struct feature_config_ctrl config_data, *config = &config_data; + u64 cfg_mask, cfg_val; + + vcpu = test_kvm_vcpu_init(test); + KUNIT_EXPECT_TRUE(test, vcpu); + if (!vcpu) + return; + + vcpu->arch.hcr_el2 = 0; + config->ftr_reg = SYS_ID_AA64MMFR1_EL1; + config->ftr_shift = 4; + config->ftr_min = 2; + config->ftr_signed = FTR_UNSIGNED; + + /* Test for hcr_el2 */ + config->cfg_reg = VCPU_HCR_EL2; + cfg_mask = 0x30000800000; + cfg_val = 0x30000800000; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.hcr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_mask, cfg_val); + + cfg_mask = 0x30000800000; + cfg_val = 0; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.hcr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_mask, cfg_val); + + /* Test for mdcr_el2 */ + config->cfg_reg = VCPU_MDCR_EL2; + cfg_mask = 0x30000800000; + cfg_val = 0x30000800000; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.mdcr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.mdcr_el2 & cfg_mask, cfg_val); + + cfg_mask = 0x30000800000; + cfg_val = 0x0; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.mdcr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.mdcr_el2 & cfg_mask, cfg_val); + + /* Test for cptr_el2 */ + config->cfg_reg = VCPU_CPTR_EL2; + cfg_mask = 0x30000800000; + cfg_val = 0x30000800000; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.cptr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.cptr_el2 & cfg_mask, cfg_val); + + cfg_mask = 0x30000800000; + cfg_val = 0x0; + config->cfg_mask = cfg_mask; + config->cfg_val = cfg_val; + + vcpu->arch.cptr_el2 = 0; + feature_trap_activate(vcpu, config); + KUNIT_EXPECT_EQ(test, vcpu->arch.cptr_el2 & cfg_mask, cfg_val); + + test_kvm_vcpu_fini(test, vcpu); +} + +static bool test_need_trap_aa64dfr0(struct kvm_vcpu *vcpu) +{ + u64 val; + + val = __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(SYS_ID_AA64DFR0_EL1)); + return ((val & 0xf) == 0); +} + +static void id_reg_features_trap_activate_test(struct kunit *test) +{ + struct kvm_vcpu *vcpu; + u32 id; + u64 cfg_mask0, cfg_val0, cfg_mask1, cfg_val1, cfg_mask2, cfg_val2; + u64 cfg_mask, cfg_val, id_reg_sys_val; + struct id_reg_info id_reg_data; + struct feature_config_ctrl *config, config0, config1, config2; + struct feature_config_ctrl *trap_features[] = { + &config0, &config1, &config2, NULL, + }; + + vcpu = test_kvm_vcpu_init(test); + KUNIT_EXPECT_TRUE(test, vcpu); + if (!vcpu) + return; + + id_reg_sys_val = 0x7777777777777777; + id = SYS_ID_AA64DFR0_EL1; + id_reg_data.sys_reg = id; + id_reg_data.sys_val = id_reg_sys_val; + id_reg_data.vcpu_limit_val = (u64)-1; + id_reg_data.trap_features = + (const struct feature_config_ctrl *(*)[])trap_features; + + cfg_mask0 = 0x3; + cfg_val0 = 0x3; + config = &config0; + memset(config, 0, sizeof(*config)); + config->ftr_reg = id; + config->ftr_shift = 60; + config->ftr_min = 2; + config->ftr_signed = FTR_UNSIGNED; + config->cfg_reg = VCPU_HCR_EL2; + config->cfg_mask = cfg_mask0; + config->cfg_val = cfg_val0; + + cfg_mask1 = 0x70000040; + cfg_val1 = 0x30000040; + config = &config1; + memset(config, 0, sizeof(*config)); + config->ftr_reg = id; + config->ftr_need_trap = test_need_trap_aa64dfr0; + config->ftr_signed = FTR_UNSIGNED; + config->cfg_reg = VCPU_HCR_EL2; + config->cfg_mask = cfg_mask1; + config->cfg_val = cfg_val1; + + /* Feature with signed ID register field */ + cfg_mask2 = 0x70000000800; + cfg_val2 = 0x30000000800; + config = &config2; + memset(config, 0, sizeof(*config)); + config->ftr_reg = id; + config->ftr_shift = 4; + config->ftr_min = 0; + config->ftr_signed = FTR_SIGNED; + config->cfg_reg = VCPU_HCR_EL2; + config->cfg_mask = cfg_mask2; + config->cfg_val = cfg_val2; + + /* Enable features for config0, 1 and 2 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = id_reg_sys_val; + + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, &id_reg_data); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0); + + /* Disable features for config0 only */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x1; + cfg_mask = cfg_mask0; + cfg_val = cfg_val0; + + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, &id_reg_data); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_mask, cfg_val); + + /* Disable features for config0 and config1 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x0; + cfg_mask = (cfg_mask0 | cfg_mask1); + cfg_val = (cfg_val0 | cfg_val1); + + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, &id_reg_data); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_mask, cfg_val); + + /* Disable features for config0, 1, and 2 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0xf0; + cfg_mask = (cfg_mask0 | cfg_mask1 | cfg_mask2); + cfg_val = (cfg_val0 | cfg_val1 | cfg_val2); + + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, &id_reg_data); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_mask, cfg_val); + + /* Test with id_reg_info == NULL */ + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, NULL); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0); + + /* Test with id_reg_data.trap_features = NULL */ + id_reg_data.trap_features = NULL; + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0xf0; + + vcpu->arch.hcr_el2 = 0; + id_reg_features_trap_activate(vcpu, &id_reg_data); + KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0); + + test_kvm_vcpu_fini(test, vcpu); +} + +static void vcpu_need_trap_ptrauth_test(struct kunit *test) +{ + struct kvm_vcpu *vcpu; + u32 id = SYS_ID_AA64ISAR1_EL1; + + vcpu = test_kvm_vcpu_init(test); + KUNIT_EXPECT_TRUE(test, vcpu); + if (!vcpu) + return; + + if (system_has_full_ptr_auth()) { + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x0; + KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu)); + + /* GPI = 1, API = 1 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x10000100; + KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu)); + + /* GPI = 1, APA = 1 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x10000010; + KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu)); + + /* GPA = 1, API = 1 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x01000100; + KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu)); + + /* GPA = 1, APA = 1 */ + __vcpu_sys_reg(vcpu, IDREG_SYS_IDX(id)) = 0x01000010; + KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu)); + } else { + KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu)); + } + + test_kvm_vcpu_fini(test, vcpu); +} + static struct kunit_case kvm_sys_regs_test_cases[] = { KUNIT_CASE_PARAM(arm64_check_feature_one_test, feature_one_gen_params), KUNIT_CASE_PARAM(arm64_check_features_test, features_gen_params), @@ -859,6 +1094,9 @@ static struct kunit_case kvm_sys_regs_test_cases[] = { KUNIT_CASE(validate_id_aa64dfr0_el1_test), KUNIT_CASE(validate_id_dfr0_el1_test), KUNIT_CASE(validate_mvfr1_el1_test), + KUNIT_CASE(vcpu_need_trap_ptrauth_test), + KUNIT_CASE(feature_trap_activate_test), + KUNIT_CASE(id_reg_features_trap_activate_test), {} };