From patchwork Tue Nov 2 00:21:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597637 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 07495C433F5 for ; Tue, 2 Nov 2021 00:23:58 +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 CA91260EE3 for ; Tue, 2 Nov 2021 00:23:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CA91260EE3 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=Zs7p9Ba++Cds4a7O2R0WZ+zhDrrsK4YcHyGO+FhyAlM=; b=Uf203hCr1mDvf/AQfk+B2FYKSq g75aa6SUCM3T4f57D2G9aW1TITI9BB1r0Hs66A/FTGZrioSFHYfOWLXn88wjCOEA+VrgJCWL7+smb RoToGmrnSSwxiqpdLYVHki3MkzaKq6VixtY48R5ptOv2ZZ2limoM5NsBnzLfPRD/BgdUSkN5ys1N6 nXA5ZxLtCG1m0b19MQn6kGU169X2i/74j3s/11xLY1EMD+0GFX+REdTdMFFsH3Gs9EjvpYvpRase1 x3u0qrQFWXNXPhOyz06Ql/X/iPN6b0MHrnGxBu/6FzKqqyv5SlHWQjE7moofXi75sa/qrixH1+VSC ZkrImNgQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZU-0004uV-RG; Tue, 02 Nov 2021 00:22:37 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZI-0004qN-Qn for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:26 +0000 Received: by mail-pf1-x44a.google.com with SMTP id s39-20020a056a0017a700b00481146e614cso2021785pfg.9 for ; Mon, 01 Nov 2021 17:22:24 -0700 (PDT) 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=463jW+eQHd/NhwZYuDMc3rk5G7snK/LY01GkhlfUtUA=; b=TkjpwxBe3ApO8JGkFpDlB3wZ3eP3OO4pdxdPuXRQLe+9GDAlLy9w/OaRheXS/vI7wD UYe4K7w1jrLxMelHsTktupi+F4DRgr8TbNCdYWFd5jlHxa5wLVCzo+j0qMZ7GP+cFLGX 9uGdIWSaGEDozNWentIFOUD80TZDjCFeRvmAhZHK1gxaS1yN6Cu2prmkgIBbVsR/yb3k gfsRwPYk+WEXMOrJ41E7GzFMfadIztUOaAT0C7HaEvsKb/nxK5izzWusXwstZBaXZwvO A5pLNj9ziN1ty+/HztgOQJ7s4hZk1gcZFS8cvx6tard/PDIBH5mXxNZ3MqKJXkyltS/D a6pA== 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=463jW+eQHd/NhwZYuDMc3rk5G7snK/LY01GkhlfUtUA=; b=UN92TWQrGa7J4vin+2REQ3kvf/Mbw6Gp3E27z4YQqYD6bk55E7R1uG9nwtbY+SHhCX GLB2nh8bkMBaDHbrMVFOQimb4mIU+dxOM/wrjLFtZ9wsE0VW7yR8NCvJYtXiZFK1M1hL NyfaZitq0w/SBQIp+tpp96sTStM20/IY12pr6M8ED1pUw2HegVrcj7Zs0pVlTZL9mtMp yfAKoAeFfX/t52dCNkCQinxt4/i9SX414i8dNDmI/BvjG8SBoNtbqwa+onk4wowbVsUq CV8Nk/zPPoQsij3nVNk8Pl0ilDeBY4NPYjdxKqUsew5DCB50d5ZMDgzTTyycHU8CdaQN 3pBQ== X-Gm-Message-State: AOAM530qcX5tPqeiRXFjMpuVDo/OZ3vKIS4ooGJTCXWRUd8fHlnSnZgF xzmGRzmGjnWSFRWjSHqCzFRRKgWSnZLV X-Google-Smtp-Source: ABdhPJyhL1p9hjD+vrdP8Wi+8/17u956mE4SVN4PZZAGIUWUMwXU/0oLflia/axZ4dls56uqFxXrcOU1q1l3 X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90b:1b0a:: with SMTP id nu10mr2584922pjb.35.1635812543564; Mon, 01 Nov 2021 17:22:23 -0700 (PDT) Date: Tue, 2 Nov 2021 00:21:56 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-2-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 1/8] KVM: arm64: Factor out firmware register handling from psci.c From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172224_939238_B4B139B7 X-CRM114-Status: GOOD ( 22.85 ) 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 Common hypercall firmware register handing is currently employed by psci.c. Since the upcoming patches add more of these registers, it's better to move the generic handling to hypercall.c for a cleaner presentation. While we are at it, collect all the firmware registers under fw_reg_ids[] to help implement kvm_arm_get_fw_num_regs() and kvm_arm_copy_fw_reg_indices() in a generic way. No functional change intended. Signed-off-by: Raghavendra Rao Ananta --- arch/arm64/kvm/guest.c | 2 +- arch/arm64/kvm/hypercalls.c | 151 +++++++++++++++++++++++++++++++ arch/arm64/kvm/psci.c | 167 +++-------------------------------- include/kvm/arm_hypercalls.h | 7 ++ include/kvm/arm_psci.h | 8 +- 5 files changed, 172 insertions(+), 163 deletions(-) diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 5ce26bedf23c..625f97f7b304 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 30da78f72b3b..d030939c5929 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -146,3 +146,154 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); return 1; } + +static const u64 fw_reg_ids[] = { + KVM_REG_ARM_PSCI_VERSION, + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, +}; + +int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) +{ + return ARRAY_SIZE(fw_reg_ids); +} + +int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fw_reg_ids); i++) { + if (put_user(fw_reg_ids[i], uindices)) + return -EFAULT; + } + + return 0; +} + +#define KVM_REG_FEATURE_LEVEL_WIDTH 4 +#define KVM_REG_FEATURE_LEVEL_MASK (BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1) + +/* + * Convert the workaround level into an easy-to-compare number, where higher + * values mean better protection. + */ +static int get_kernel_wa_level(u64 regid) +{ + switch (regid) { + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: + switch (arm64_get_spectre_v2_state()) { + case SPECTRE_VULNERABLE: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; + case SPECTRE_MITIGATED: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL; + case SPECTRE_UNAFFECTED: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED; + } + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: + switch (arm64_get_spectre_v4_state()) { + case SPECTRE_MITIGATED: + /* + * As for the hypercall discovery, we pretend we + * don't have any FW mitigation if SSBS is there at + * all times. + */ + if (cpus_have_final_cap(ARM64_SSBS)) + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; + fallthrough; + case SPECTRE_UNAFFECTED: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED; + case SPECTRE_VULNERABLE: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; + } + } + + return -EINVAL; +} + +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) +{ + void __user *uaddr = (void __user *)(long)reg->addr; + u64 val; + + switch (reg->id) { + case KVM_REG_ARM_PSCI_VERSION: + val = kvm_psci_version(vcpu, vcpu->kvm); + break; + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: + val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; + break; + default: + return -ENOENT; + } + + if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) + return -EFAULT; + + return 0; +} + +int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) +{ + void __user *uaddr = (void __user *)(long)reg->addr; + u64 val; + int wa_level; + + if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) + return -EFAULT; + + switch (reg->id) { + case KVM_REG_ARM_PSCI_VERSION: + return kvm_arm_set_psci_fw_reg(vcpu, val); + + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: + if (val & ~KVM_REG_FEATURE_LEVEL_MASK) + return -EINVAL; + + if (get_kernel_wa_level(reg->id) < val) + return -EINVAL; + + return 0; + + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: + if (val & ~(KVM_REG_FEATURE_LEVEL_MASK | + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED)) + return -EINVAL; + + /* The enabled bit must not be set unless the level is AVAIL. */ + if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) && + (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL) + return -EINVAL; + + /* + * Map all the possible incoming states to the only two we + * really want to deal with. + */ + switch (val & KVM_REG_FEATURE_LEVEL_MASK) { + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN: + wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; + break; + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED: + wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED; + break; + default: + return -EINVAL; + } + + /* + * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the + * other way around. + */ + if (get_kernel_wa_level(reg->id) < wa_level) + return -EINVAL; + + return 0; + default: + return -ENOENT; + } + + return -EINVAL; +} diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c index 74c47d420253..b9bcbc919b19 100644 --- a/arch/arm64/kvm/psci.c +++ b/arch/arm64/kvm/psci.c @@ -404,168 +404,25 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) }; } -int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) +int kvm_arm_set_psci_fw_reg(struct kvm_vcpu *vcpu, u64 val) { - return 3; /* PSCI version and two workaround registers */ -} - -int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) -{ - if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices++)) - return -EFAULT; - - if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, uindices++)) - return -EFAULT; - - if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++)) - return -EFAULT; - - return 0; -} + bool wants_02; -#define KVM_REG_FEATURE_LEVEL_WIDTH 4 -#define KVM_REG_FEATURE_LEVEL_MASK (BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1) - -/* - * Convert the workaround level into an easy-to-compare number, where higher - * values mean better protection. - */ -static int get_kernel_wa_level(u64 regid) -{ - switch (regid) { - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - switch (arm64_get_spectre_v2_state()) { - case SPECTRE_VULNERABLE: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; - case SPECTRE_MITIGATED: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL; - case SPECTRE_UNAFFECTED: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED; - } - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: - switch (arm64_get_spectre_v4_state()) { - case SPECTRE_MITIGATED: - /* - * As for the hypercall discovery, we pretend we - * don't have any FW mitigation if SSBS is there at - * all times. - */ - if (cpus_have_final_cap(ARM64_SSBS)) - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; - fallthrough; - case SPECTRE_UNAFFECTED: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED; - case SPECTRE_VULNERABLE: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; - } - } + wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); - return -EINVAL; -} - -int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) -{ - void __user *uaddr = (void __user *)(long)reg->addr; - u64 val; - - switch (reg->id) { - case KVM_REG_ARM_PSCI_VERSION: - val = kvm_psci_version(vcpu, vcpu->kvm); - break; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: - val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; - break; - default: - return -ENOENT; - } - - if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) - return -EFAULT; - - return 0; -} - -int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) -{ - void __user *uaddr = (void __user *)(long)reg->addr; - u64 val; - int wa_level; - - if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) - return -EFAULT; - - switch (reg->id) { - case KVM_REG_ARM_PSCI_VERSION: - { - bool wants_02; - - wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); - - switch (val) { - case KVM_ARM_PSCI_0_1: - if (wants_02) - return -EINVAL; - vcpu->kvm->arch.psci_version = val; - return 0; - case KVM_ARM_PSCI_0_2: - case KVM_ARM_PSCI_1_0: - if (!wants_02) - return -EINVAL; - vcpu->kvm->arch.psci_version = val; - return 0; - } - break; - } - - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - if (val & ~KVM_REG_FEATURE_LEVEL_MASK) - return -EINVAL; - - if (get_kernel_wa_level(reg->id) < val) + switch (val) { + case KVM_ARM_PSCI_0_1: + if (wants_02) return -EINVAL; - + vcpu->kvm->arch.psci_version = val; return 0; - - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: - if (val & ~(KVM_REG_FEATURE_LEVEL_MASK | - KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED)) - return -EINVAL; - - /* The enabled bit must not be set unless the level is AVAIL. */ - if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) && - (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL) - return -EINVAL; - - /* - * Map all the possible incoming states to the only two we - * really want to deal with. - */ - switch (val & KVM_REG_FEATURE_LEVEL_MASK) { - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN: - wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; - break; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED: - wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED; - break; - default: - return -EINVAL; - } - - /* - * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the - * other way around. - */ - if (get_kernel_wa_level(reg->id) < wa_level) + case KVM_ARM_PSCI_0_2: + case KVM_ARM_PSCI_1_0: + if (!wants_02) return -EINVAL; - + vcpu->kvm->arch.psci_version = val; return 0; default: - return -ENOENT; + return -EINVAL; } - - return -EINVAL; } diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index 0e2509d27910..5d38628a8d04 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -40,4 +40,11 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu, vcpu_set_reg(vcpu, 3, a3); } +struct kvm_one_reg; + +int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu); +int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); +int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); + #endif diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h index 5b58bd2fe088..eddbd7d805e9 100644 --- a/include/kvm/arm_psci.h +++ b/include/kvm/arm_psci.h @@ -41,12 +41,6 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm) int kvm_psci_call(struct kvm_vcpu *vcpu); - -struct kvm_one_reg; - -int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu); -int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); -int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); -int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); +int kvm_arm_set_psci_fw_reg(struct kvm_vcpu *vcpu, u64 val); #endif /* __KVM_ARM_PSCI_H__ */ From patchwork Tue Nov 2 00:21:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597641 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 04F51C433F5 for ; Tue, 2 Nov 2021 00:24:13 +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 CAECB60EE3 for ; Tue, 2 Nov 2021 00:24:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CAECB60EE3 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=usmRqSxG+GpZs5g74Vcp6PG9uWJf4w2KpmPNj3Ax8Pc=; b=KhFbqJPqGABeaQZNXhZ89E8QAW GmMO0Fi1xPtmKCbdlHSfEHeRdk0l6PTr1WRZuSZ03oZx9PIx8+YV8YejsAk+LFJvrl9yhkC3xTKb+ gStD/L5JEdCyfoHB+LFRuInmbxjnmna/hLBd29Scsh4Hp69fzwietomnvHjS/uXHOX7Go25sYDAqm gbr3JRGG2/NrJe6JASq9L1+PlmMTb8dD9v9775UbuNpl/UQWbLelbeKzN1IBrZBAGJVwfNQFIZYHn ztohGo2vGqWfghZ70W0GCmwsxnsMkXp5OLybjvffr8Gu15Hy+jMuEk5KOQUoXyincdQ88nw7YL7UM od/HFlzA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZi-0004zf-FK; Tue, 02 Nov 2021 00:22:50 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZL-0004rD-Qf for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:29 +0000 Received: by mail-pg1-x549.google.com with SMTP id z4-20020a634c04000000b00299bdd9abdbso10221437pga.13 for ; Mon, 01 Nov 2021 17:22:27 -0700 (PDT) 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=hPqT43aj6nY4JmFWc0P3u2Z1LLF2JnBNG4boSS8J4fE=; b=mxHWwBOOucV4ivRJ4WUAygrlSxktQUTDc8uv8yPlgR1RaXnPzPDYQHKjAAhaiOGFZi sxMXMScEG+Vlj44ByweTMNX4aD1PRm38CB2O5bAQz7RA9gtprCuFqIoNrnhUtFIjgM8l 99whUuqnAm4bY1OnvkUrULvNlguYxHm5lmr1WNMzPG8Q/fF/QTaTL82llwWWqH6ICifH hkGIwdMxL7G1Wuj5LfZRuBa9LFWHioS8wrXXOXau8rI0whlZu6J1jZv75nLCr6Uhxmt6 D5HtTtAresWKS6qd2FIRkhSZW5y9IwF9o5oBI1z7M2uGMvnUZWvs1JLpCJb/tDF8sJis i5KQ== 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=hPqT43aj6nY4JmFWc0P3u2Z1LLF2JnBNG4boSS8J4fE=; b=RRZgnEuPE50p1ewX6Q/NUc6r7Rt3vxBOCXeRlHSgINgyZqoHFWm6wVa70szFXjTa7H TGgUsqNAIH2ftT70UZiSei5rvPV9xwmsCIbdVv0UOHS8IOTsDprnVH5YLKTCGcLNkJ4L whXgHv9qqDHy+EAHUp7a9DhriZRPrP41pKNhFr1lvXwKpPU4pDIMajf2MfZge50IT4ni GlI/uIlPHZHx4iuzHCZSeD1AU06La1Zn9OyBxVOV928fJfltmTzTrOhMNJeErMl2igH9 o9Zx6lXoVxlRP/K8xv6i6+JfuTl6pczqvlHG0RRp0kMxMed32fgP2E5f/kpsW8cHl4Iu DCcQ== X-Gm-Message-State: AOAM532e2/mXJmrsJJx+eodkxqAcfxTRHRNAcPNPVO97Cw5d8R75X86l MZUyNlUPaK+wAhvusFnglpjihF6jSNOA X-Google-Smtp-Source: ABdhPJxthlYooPKxIImySxtUb93JZ9YktYOntoS3BLY4YGfcx/3dVHrNX51FUZU2jqeG/Y6UDgsSNbqVkis7 X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6a00:2ad:b0:480:fae5:2693 with SMTP id q13-20020a056a0002ad00b00480fae52693mr14727650pfs.37.1635812546584; Mon, 01 Nov 2021 17:22:26 -0700 (PDT) Date: Tue, 2 Nov 2021 00:21:57 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-3-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 2/8] KVM: arm64: Setup base for hypercall firmware registers From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172227_906911_58896D45 X-CRM114-Status: GOOD ( 27.96 ) 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 The hypercall firmware registers may hold versioning information for a particular hypercall service. Before a VM starts, these registers are read/write to the user-space. That is, it can freely modify the fields as it sees fit for the guest. However, this shouldn't be allowed once the VM is started since it may confuse the guest as it may have read an older value. As a result, introduce a helper interface to convert the registers to read-only once any vCPU starts running. Extend this interface to also clear off all the feature bitmaps of the firmware registers upon first write. Since KVM exposes an upper limit of the feature-set to user-space via these registers, this action will ensure that no new features get enabled by accident if the user-space isn't aware of a newly added register. Since the upcoming changes introduces more firmware registers, rename the documentation to PSCI (psci.rst) to a more generic hypercall.rst. Signed-off-by: Raghavendra Rao Ananta --- .../virt/kvm/arm/{psci.rst => hypercalls.rst} | 24 +++---- Documentation/virt/kvm/arm/index.rst | 2 +- arch/arm64/include/asm/kvm_host.h | 8 +++ arch/arm64/kvm/arm.c | 7 +++ arch/arm64/kvm/hypercalls.c | 62 +++++++++++++++++++ 5 files changed, 90 insertions(+), 13 deletions(-) rename Documentation/virt/kvm/arm/{psci.rst => hypercalls.rst} (81%) diff --git a/Documentation/virt/kvm/arm/psci.rst b/Documentation/virt/kvm/arm/hypercalls.rst similarity index 81% rename from Documentation/virt/kvm/arm/psci.rst rename to Documentation/virt/kvm/arm/hypercalls.rst index d52c2e83b5b8..85dfd682d811 100644 --- a/Documentation/virt/kvm/arm/psci.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -1,22 +1,19 @@ .. SPDX-License-Identifier: GPL-2.0 -========================================= -Power State Coordination Interface (PSCI) -========================================= +======================= +ARM Hypercall Interface +======================= -KVM implements the PSCI (Power State Coordination Interface) -specification in order to provide services such as CPU on/off, reset -and power-off to the guest. - -The PSCI specification is regularly updated to provide new features, -and KVM implements these updates if they make sense from a virtualization +New hypercalls are regularly added by ARM specifications (or KVM), and +are made available to the guests if they make sense from a virtualization point of view. This means that a guest booted on two different versions of KVM can observe two different "firmware" revisions. This could cause issues if -a given guest is tied to a particular PSCI revision (unlikely), or if -a migration causes a different PSCI version to be exposed out of the -blue to an unsuspecting guest. +a given guest is tied to a particular version of a specific hypercall +(PSCI revision for instance (unlikely)), or if a migration causes a +different (PSCI) version to be exposed out of the blue to an unsuspecting +guest. In order to remedy this situation, KVM exposes a set of "firmware pseudo-registers" that can be manipulated using the GET/SET_ONE_REG @@ -26,6 +23,9 @@ to a convenient value if required. The following register is defined: * KVM_REG_ARM_PSCI_VERSION: + KVM implements the PSCI (Power State Coordination Interface) + specification in order to provide services such as CPU on/off, reset + and power-off to the guest. - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set (and thus has already been initialized) diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index 78a9b670aafe..e84848432158 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst @@ -8,6 +8,6 @@ ARM :maxdepth: 2 hyp-abi - psci + hypercalls pvtime ptp_kvm diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index d0221fb69a60..0b2502494a17 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -102,6 +102,11 @@ struct kvm_s2_mmu { struct kvm_arch_memory_slot { }; +struct hvc_reg_desc { + bool write_disabled; + bool write_attempted; +}; + struct kvm_arch { struct kvm_s2_mmu mmu; @@ -137,6 +142,9 @@ struct kvm_arch { /* Memory Tagging Extension enabled for the guest */ bool mte_enabled; + + /* Hypercall firmware registers' information */ + struct hvc_reg_desc hvc_desc; }; struct kvm_vcpu_fault_info { diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 24a1e86d7128..f9a25e439e99 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -630,6 +630,13 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) if (kvm_vm_is_protected(kvm)) kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu); + /* Mark the hypercall firmware registers as read-only since + * at least once vCPU is about to start running. + */ + mutex_lock(&kvm->lock); + kvm->arch.hvc_desc.write_disabled = true; + mutex_unlock(&kvm->lock); + return ret; } diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index d030939c5929..7e873206a05b 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -58,6 +58,12 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) val[3] = lower_32_bits(cycles); } +static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg) +{ + /* No firmware registers supporting hvc bitmaps exits yet */ + return NULL; +} + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { u32 func_id = smccc_get_function(vcpu); @@ -234,15 +240,71 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) return 0; } +static void kvm_fw_regs_sanitize(struct kvm *kvm, struct hvc_reg_desc *hvc_desc) +{ + unsigned int i; + u64 *hc_bmap = NULL; + + mutex_lock(&kvm->lock); + + if (hvc_desc->write_attempted) + goto out; + + hvc_desc->write_attempted = true; + + for (i = 0; i < ARRAY_SIZE(fw_reg_ids); i++) { + hc_bmap = kvm_fw_reg_to_bmap(kvm, fw_reg_ids[i]); + if (hc_bmap) + *hc_bmap = 0; + } + +out: + mutex_unlock(&kvm->lock); +} + +static bool +kvm_fw_regs_block_write(struct kvm *kvm, struct hvc_reg_desc *hvc_desc, u64 val) +{ + bool ret = false; + unsigned int i; + u64 *hc_bmap = NULL; + + mutex_lock(&kvm->lock); + + for (i = 0; i < ARRAY_SIZE(fw_reg_ids); i++) { + hc_bmap = kvm_fw_reg_to_bmap(kvm, fw_reg_ids[i]); + if (hc_bmap) + break; + } + + if (!hc_bmap) + goto out; + + /* Do not allow any updates if the VM has already started */ + if (hvc_desc->write_disabled && val != *hc_bmap) + ret = true; + +out: + mutex_unlock(&kvm->lock); + return ret; +} + int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { void __user *uaddr = (void __user *)(long)reg->addr; + struct kvm *kvm = vcpu->kvm; + struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc; u64 val; int wa_level; if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT; + if (kvm_fw_regs_block_write(kvm, hvc_desc, val)) + return -EBUSY; + + kvm_fw_regs_sanitize(kvm, hvc_desc); + switch (reg->id) { case KVM_REG_ARM_PSCI_VERSION: return kvm_arm_set_psci_fw_reg(vcpu, val); From patchwork Tue Nov 2 00:21:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597643 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 10006C433EF for ; Tue, 2 Nov 2021 00:24:42 +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 CF35560F56 for ; Tue, 2 Nov 2021 00:24:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CF35560F56 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=WgQCRivNhj+U1pwe5tzxSbHn2ZbuGhuLq1Xh05HOCxI=; b=YaWI//hTj3o5IJJ2CssJjzp+fh /asjhNp4uHRax0k4eE0cCsxYx29o6BU/OjUMJtgWrkpcSRgjxgme1vfw6rSgyttHHvKrJ1Z9yni9e AXR7oBuY8/lfwTilNYNzJzoTGctc3uslbJ0g3RDFsuxgz5r73tRacWNenqf39yLseFxGds+3Dz3Ey uMxQUhvxarJoC8lCCZkoj8fzAwQ0QpcvoBhEHoRvUVmZ+CIDImP4yZIAoL8YvjM1WVXmXGnFM5gkO zVje6T2rIlVE9C0DHSOnyieKRBNUyEyb3XjHurU8LfChWi1wZ0qpOG/dj1lMHZpDzdoCFX+PqWnAT GpmBiWZg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZx-00055n-Oc; Tue, 02 Nov 2021 00:23:05 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZO-0004sL-SE for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:32 +0000 Received: by mail-pg1-x549.google.com with SMTP id h10-20020a63df4a000000b002a6ba425b58so5969250pgj.17 for ; Mon, 01 Nov 2021 17:22:29 -0700 (PDT) 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=5xdTVyalAPBF7xz88s2AG3TjJTlI3TQIsxRlDSe0JkY=; b=owVjVVcVbh0xkTz3QzRHqiRw2HHotZuS/eRp3eMwkvUBKm+RR33BROcVAkLmlRjXq/ 9CWfXFrTawJ58w6XZXFnipv2i2oSQsmudxW/uOzEuIeDC0Vao8xGoA4sowrutF4jvLrt du9mfrMqQXjN1aX6m3KboD3t5x/j3H/qt1zviWcS3LwaQ5z0ow/9dpmarAx5KnDiDw8k e6h+2RjSpmJEGNotZC3bemh9b9uPddj4ZcdWXyQ0kUn1lmKa17hEU3k9uIvOUGCsAbIi +Y+2dE/77lBlWxtqtDTxdQwMTo5/UHdfjGj68Bx3jrkdrHl08X4/i/yzwMQTY7m4FzzO WWSA== 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=5xdTVyalAPBF7xz88s2AG3TjJTlI3TQIsxRlDSe0JkY=; b=7D5GRyjYkSA6cqXhHH2CQPELTFmWf4ke7Yr+S5IYc+QtMWqszY0LCGYfGpjKvXmBOU DcGBsTRbGVYsBiqDnVW7a13o+z3rs3PgiYCnOM+fbUhIF7xxSmJg0/Py7egCzJXpnkT6 Hw2Lhrzt4jrw6Kg75ptv4g0x34c1KvpmoM8unvAf9UKNT5ONeGQp81ZlnIC9ApU4Sprh 2qejAuUspc22/mRmv254eJF4jHhDb8BZu2iyd172g8Si8O5z64sSZo+RPXZw4FQ2Z6Xy NqCZ8N2ZwNdOs27W0goks/U4fuHVUBL/5u1jjDhUTJvXrNXAR9HXYLyScrwva4eTDSTv FodQ== X-Gm-Message-State: AOAM530et5Bx/5LQcILWNwx1J0HBw69wcaYQpwPI3S88MUrTx0VmOA5E fp+SqG0zLTaxRUfWwJFmPHv7dv/ZmUkS X-Google-Smtp-Source: ABdhPJzZEqgUeJgATqjGUl0f/QIqFxqe2/y4mcpsTTyzYZ+Z383m2c+iUMmGn6d3UAwmoVgKEgZmuwvajwWg X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90a:c3:: with SMTP id v3mr216906pjd.0.1635812548862; Mon, 01 Nov 2021 17:22:28 -0700 (PDT) Date: Tue, 2 Nov 2021 00:21:58 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-4-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 3/8] KVM: arm64: Add standard secure service calls firmware register From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172230_954351_307D74BD X-CRM114-Status: GOOD ( 25.85 ) 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 Introduce a firmware register that encapsulates standard secure service calls (owner value 4) as a bitmap. Depending on how the user-space configures the register, the features will be enabled or disabled for the guest. Currently, this includes support only for ARM True Random Number Generator (TRNG) service, with bit-0 of the register representing mandatory features of v1.0. Signed-off-by: Raghavendra Rao Ananta --- Documentation/virt/kvm/arm/hypercalls.rst | 17 +++++ arch/arm64/include/asm/kvm_host.h | 2 + arch/arm64/include/uapi/asm/kvm.h | 6 ++ arch/arm64/kvm/arm.c | 8 +++ arch/arm64/kvm/hypercalls.c | 75 ++++++++++++++++++++++- arch/arm64/kvm/trng.c | 9 +-- include/kvm/arm_hypercalls.h | 5 ++ 7 files changed, 113 insertions(+), 9 deletions(-) diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst index 85dfd682d811..1601919f256d 100644 --- a/Documentation/virt/kvm/arm/hypercalls.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -20,6 +20,14 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG interface. These registers can be saved/restored by userspace, and set to a convenient value if required. +The firmware register KVM_REG_ARM_STD exposes the hypercall services +in the form of a feature bitmap. Upon VM creation, by default, KVM exposes +all the features to the guest, which can be learnt using GET_ONE_REG +interface. Conversely, the features can be enabled or disabled via the +SET_ONE_REG interface. These registers allow the user-space modification +only until the VM has started running, after which they turn to read-only +registers. SET_ONE_REG in this scenario will return -EBUSY. + The following register is defined: * KVM_REG_ARM_PSCI_VERSION: @@ -74,4 +82,13 @@ The following register is defined: KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED: The workaround is always active on this vCPU or it is not needed. +* KVM_REG_ARM_STD: + Controls the bitmap of the ARM Standard Secure Service Calls. + + The following bits are accepted: + + KVM_REG_ARM_STD_TRNG_V1_0: + The bit represents the services offered under v1.0 of ARM True Random Number Generator + (TRNG) specification (ARM DEN 0098). + .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 0b2502494a17..176d6be7b4da 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -105,6 +105,8 @@ struct kvm_arch_memory_slot { struct hvc_reg_desc { bool write_disabled; bool write_attempted; + + u64 kvm_std_bmap; }; struct kvm_arch { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index b3edde68bc3e..6387dea5396d 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -281,6 +281,12 @@ struct kvm_arm_copy_mte_tags { #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) +#define KVM_REG_ARM_STD KVM_REG_ARM_FW_REG(3) +enum kvm_reg_arm_std_bmap { + KVM_REG_ARM_STD_TRNG_V1_0, + KVM_REG_ARM_STD_BMAP_MAX, +}; + /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index f9a25e439e99..1cf58aa49222 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -130,6 +130,13 @@ static void set_default_spectre(struct kvm *kvm) kvm->arch.pfr0_csv3 = 1; } +static void set_default_hypercalls(struct kvm *kvm) +{ + struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc; + + hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES; +} + /** * kvm_arch_init_vm - initializes a VM data structure * @kvm: pointer to the KVM struct @@ -156,6 +163,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) kvm->arch.max_vcpus = kvm_arm_default_max_vcpus(); set_default_spectre(kvm); + set_default_hypercalls(kvm); return ret; out_free_stage2_pgd: diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 7e873206a05b..0b3006353bf6 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -60,8 +60,64 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg) { - /* No firmware registers supporting hvc bitmaps exits yet */ - return NULL; + struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc; + + switch (fw_reg) { + case KVM_REG_ARM_STD: + return &hvc_desc->kvm_std_bmap; + default: + return NULL; + } +} + +struct kvm_hvc_func_map { + u32 func_id; + u64 bmap_bit; +}; + +#define HVC_FUNC_MAP_DESC(func, bit) \ + { \ + .func_id = func, \ + .bmap_bit = bit, \ + } + +static const struct kvm_hvc_func_map hvc_std_map[] = { + HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_GET_UUID, KVM_REG_ARM_STD_TRNG_V1_0), + HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND32, KVM_REG_ARM_STD_TRNG_V1_0), + HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND64, KVM_REG_ARM_STD_TRNG_V1_0), +}; + +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) +{ + struct kvm *kvm = vcpu->kvm; + u8 hvc_owner = ARM_SMCCC_OWNER_NUM(func_id); + const struct kvm_hvc_func_map *hvc_func_map = NULL; + + u64 fw_reg, *hc_bmap; + unsigned int map_sz, i; + + switch (hvc_owner) { + case ARM_SMCCC_OWNER_STANDARD: + fw_reg = KVM_REG_ARM_STD; + hvc_func_map = hvc_std_map; + map_sz = ARRAY_SIZE(hvc_std_map); + break; + default: + /* Allow all the owners that aren't mapped */ + return true; + } + + hc_bmap = kvm_fw_reg_to_bmap(kvm, fw_reg); + if (!hc_bmap) + return true; + + for (i = 0; i < map_sz; i++) { + if (func_id == hvc_func_map[i].func_id) + return *hc_bmap & BIT(hvc_func_map[i].bmap_bit); + } + + /* Allow all the functions of an owner that aren't mapped */ + return true; } int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) @@ -71,6 +127,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) u32 feature; gpa_t gpa; + if (!kvm_hvc_call_supported(vcpu, func_id)) + goto out; + switch (func_id) { case ARM_SMCCC_VERSION_FUNC_ID: val[0] = ARM_SMCCC_VERSION_1_1; @@ -149,6 +208,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) return kvm_psci_call(vcpu); } +out: smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); return 1; } @@ -157,6 +217,7 @@ static const u64 fw_reg_ids[] = { KVM_REG_ARM_PSCI_VERSION, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, + KVM_REG_ARM_STD, }; int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) @@ -219,6 +280,7 @@ static int get_kernel_wa_level(u64 regid) int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { + struct hvc_reg_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc; void __user *uaddr = (void __user *)(long)reg->addr; u64 val; @@ -230,6 +292,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; break; + case KVM_REG_ARM_STD: + val = hvc_desc->kvm_std_bmap; + break; default: return -ENOENT; } @@ -352,6 +417,12 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) if (get_kernel_wa_level(reg->id) < wa_level) return -EINVAL; + return 0; + case KVM_REG_ARM_STD: + if (val & ~ARM_SMCCC_STD_FEATURES) + return -EINVAL; + + hvc_desc->kvm_std_bmap = val; return 0; default: return -ENOENT; diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c index 99bdd7103c9c..6dff765f5b9b 100644 --- a/arch/arm64/kvm/trng.c +++ b/arch/arm64/kvm/trng.c @@ -60,14 +60,9 @@ int kvm_trng_call(struct kvm_vcpu *vcpu) val = ARM_SMCCC_TRNG_VERSION_1_0; break; case ARM_SMCCC_TRNG_FEATURES: - switch (smccc_get_arg1(vcpu)) { - case ARM_SMCCC_TRNG_VERSION: - case ARM_SMCCC_TRNG_FEATURES: - case ARM_SMCCC_TRNG_GET_UUID: - case ARM_SMCCC_TRNG_RND32: - case ARM_SMCCC_TRNG_RND64: + if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu))) val = TRNG_SUCCESS; - } + break; case ARM_SMCCC_TRNG_GET_UUID: smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]), diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index 5d38628a8d04..5f01bb139312 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -6,6 +6,9 @@ #include +#define ARM_SMCCC_STD_FEATURES \ + GENMASK_ULL(KVM_REG_ARM_STD_BMAP_MAX - 1, 0) + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); static inline u32 smccc_get_function(struct kvm_vcpu *vcpu) @@ -47,4 +50,6 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id); + #endif From patchwork Tue Nov 2 00:21:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597645 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 76A9EC433F5 for ; Tue, 2 Nov 2021 00:25:01 +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 3FA1260EDF for ; Tue, 2 Nov 2021 00:25:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 3FA1260EDF 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=IxlCMYNJg50gtgbQCy4uH+vSv4B1b/FxUQ6bGnkM2a8=; b=fdOYVVB/+XnYU8XX1OWrJUJeS7 srbhiTlh+Bc48qvzYclAl66vk7MUmYj7bSg4C6WCkPYGrBVDNS1DcvANV9WEN4atQVOum77yPwTXL oX11m1Uk0p+HgjYn27VqkoaPpNRlcbiYT0ZDZMHBrWtLRiGcEOI1wJy0ILaSPPhDvPnaGcPAQiHRB poyP02TBz2szwcqF8sPqB1caEm5JH7L7mgTXsut+z58uzdvZMfDW88py0PFWj5CA2ercIGVYnoKBk +GAACL4qtsaREVzkGWymJdJ/q1wxmWrL090fOyb11lsSUckKnPu6zcCTbKbwh2e9PRzrpQoGz2nA7 gpO2f6ZQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhaC-0005Cz-Sp; Tue, 02 Nov 2021 00:23:21 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZR-0004sw-22 for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:34 +0000 Received: by mail-pf1-x44a.google.com with SMTP id a26-20020aa795ba000000b0048102d73f10so2951898pfk.6 for ; Mon, 01 Nov 2021 17:22:32 -0700 (PDT) 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=Chm/T8yL3ygYrjvri7zfXhNFj/zx6GP1hVE4sMZ+a+w=; b=nN5gKUrFIqzx6CmBSS42DcfwFEpyDsegSFkgJjEQRTH4nwB4hAJbyU1slAbrRmMybH GP7ZzaU7vH0nbVkk0NGjh0fvvwDwguas2GMfEJfWS980D3reVJLje5eQERco2XDriuAD cC5X6GqVWKgR++ugI/Vnoi6YUkr1vqima0lpWMNkq/rcy6mzMjfmeYoq7Mp39T6iQ1gm n+RjTftFmodXfL0ZdpU1lgbAZQRM1F0WxusdGwSMFLbfS3V2aHdcRdA6wcFS9EAE5h8b RE99uIg7ik08KPFXWgW/xyfkOOqknGc1f9/n1/DnojcaJ+dzhxWeytk/l9mLkxF3J+/s +bNw== 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=Chm/T8yL3ygYrjvri7zfXhNFj/zx6GP1hVE4sMZ+a+w=; b=AbNFZ86erL6G6WWd/nZcOVIBpOSQnUFVN+EZJ3JGsrx5TVAjz0A6IHQB1o1wqizyoP KubzUjfoQy77QPBUkEu5mfKzXeiZvDn2+mbGrg+5lqS0+TTRWU6OK+HkeU1jeQjPpPSh Te/Hgw9W9TVB7fHPf70uMkMb3eSYx815X6OrrBA4ru7CyxZ5LLuI/fwu76KsxX24frle F6BEjftX0DI0wByK7VXqIoRsfeBRKVrZQF+ZUTzEVyD5aZCCdhrS8BUjXq1l54MwkvOU KXB2UB5VOBd4D9/LYxbWBI4fxHIgtVop/KPviQbfEJsZKjMGgCRKrTn6m5KDbIGXzTlI +X6Q== X-Gm-Message-State: AOAM533z8ixipA8iNFL4AieMmwaVOIt6Ohp1ushbXzDE7LobFWCz/Nsj bpgfB+A/gwBr2cchZUaAbf4avM2hjuOW X-Google-Smtp-Source: ABdhPJzwWL9vAsGyyzKtoA+qSmHdO5GSQso3+7zYZ8kWXJoBSLwa7gOBkk12voU8VEShgrYWhIwnPdrYS+HE X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90b:1c05:: with SMTP id oc5mr2560695pjb.179.1635812551611; Mon, 01 Nov 2021 17:22:31 -0700 (PDT) Date: Tue, 2 Nov 2021 00:21:59 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-5-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 4/8] KVM: arm64: Add standard hypervisor service calls firmware register From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172233_145866_57148D27 X-CRM114-Status: GOOD ( 19.28 ) 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 Introduce the firmware register to hold the standard hypervisor service calls (owner value 5) as a bitmap. The bitmap represents the features that'll be enabled for the guest, as configured by the user-space. Currently, this includes support only for Paravirtualized time, represented by bit-0. Signed-off-by: Raghavendra Rao Ananta --- Documentation/virt/kvm/arm/hypercalls.rst | 23 ++++++++++++++++------- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/include/uapi/asm/kvm.h | 6 ++++++ arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hypercalls.c | 22 ++++++++++++++++++++++ arch/arm64/kvm/pvtime.c | 3 +++ include/kvm/arm_hypercalls.h | 3 +++ 7 files changed, 52 insertions(+), 7 deletions(-) diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst index 1601919f256d..2cb82c694868 100644 --- a/Documentation/virt/kvm/arm/hypercalls.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -20,13 +20,13 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG interface. These registers can be saved/restored by userspace, and set to a convenient value if required. -The firmware register KVM_REG_ARM_STD exposes the hypercall services -in the form of a feature bitmap. Upon VM creation, by default, KVM exposes -all the features to the guest, which can be learnt using GET_ONE_REG -interface. Conversely, the features can be enabled or disabled via the -SET_ONE_REG interface. These registers allow the user-space modification -only until the VM has started running, after which they turn to read-only -registers. SET_ONE_REG in this scenario will return -EBUSY. +The firmware registers, KVM_REG_ARM_STD and KVM_REG_ARM_STD_HYP exposes +the hypercall services in the form of a feature bitmap. Upon VM creation, +by default, KVM exposes all the features to the guest, which can be learnt +using GET_ONE_REG interface. Conversely, the features can be enabled or +disabled via the SET_ONE_REG interface. These registers allow the user-space +modification only until the VM has started running, after which they turn to +read-only registers. SET_ONE_REG in this scenario will return -EBUSY. The following register is defined: @@ -91,4 +91,13 @@ The following register is defined: The bit represents the services offered under v1.0 of ARM True Random Number Generator (TRNG) specification (ARM DEN 0098). +* KVM_REG_ARM_STD_HYP + Controls the bitmap of the ARM Standard Hypervisor Service Calls. + + The following bits are accepted: + + KVM_REG_ARM_STD_HYP_PV_TIME_ST: + The bit represents the Paravirtualized Time service (also known as stolen time) as + represented by ARM DEN0057A. + .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 176d6be7b4da..cee4f4b8a756 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -107,6 +107,7 @@ struct hvc_reg_desc { bool write_attempted; u64 kvm_std_bmap; + u64 kvm_std_hyp_bmap; }; struct kvm_arch { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 6387dea5396d..46701da1a27d 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -287,6 +287,12 @@ enum kvm_reg_arm_std_bmap { KVM_REG_ARM_STD_BMAP_MAX, }; +#define KVM_REG_ARM_STD_HYP KVM_REG_ARM_FW_REG(4) +enum kvm_reg_arm_std_hyp_bmap { + KVM_REG_ARM_STD_HYP_PV_TIME_ST, + KVM_REG_ARM_STD_HYP_BMAP_MAX, +}; + /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 1cf58aa49222..1c69d2a71b86 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -135,6 +135,7 @@ static void set_default_hypercalls(struct kvm *kvm) struct hvc_reg_desc *hvc_desc = &kvm->arch.hvc_desc; hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES; + hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES; } /** diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 0b3006353bf6..46064c515058 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -65,6 +65,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg) switch (fw_reg) { case KVM_REG_ARM_STD: return &hvc_desc->kvm_std_bmap; + case KVM_REG_ARM_STD_HYP: + return &hvc_desc->kvm_std_hyp_bmap; default: return NULL; } @@ -87,6 +89,10 @@ static const struct kvm_hvc_func_map hvc_std_map[] = { HVC_FUNC_MAP_DESC(ARM_SMCCC_TRNG_RND64, KVM_REG_ARM_STD_TRNG_V1_0), }; +static const struct kvm_hvc_func_map hvc_std_hyp_map[] = { + HVC_FUNC_MAP_DESC(ARM_SMCCC_HV_PV_TIME_ST, KVM_REG_ARM_STD_HYP_PV_TIME_ST), +}; + bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) { struct kvm *kvm = vcpu->kvm; @@ -102,6 +108,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) hvc_func_map = hvc_std_map; map_sz = ARRAY_SIZE(hvc_std_map); break; + case ARM_SMCCC_OWNER_STANDARD_HYP: + fw_reg = KVM_REG_ARM_STD_HYP; + hvc_func_map = hvc_std_hyp_map; + map_sz = ARRAY_SIZE(hvc_std_hyp_map); + break; default: /* Allow all the owners that aren't mapped */ return true; @@ -218,6 +229,7 @@ static const u64 fw_reg_ids[] = { KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, KVM_REG_ARM_STD, + KVM_REG_ARM_STD_HYP, }; int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) @@ -295,6 +307,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) case KVM_REG_ARM_STD: val = hvc_desc->kvm_std_bmap; break; + case KVM_REG_ARM_STD_HYP: + val = hvc_desc->kvm_std_hyp_bmap; + break; default: return -ENOENT; } @@ -424,6 +439,13 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) hvc_desc->kvm_std_bmap = val; return 0; + + case KVM_REG_ARM_STD_HYP: + if (val & ~ARM_SMCCC_STD_HYP_FEATURES) + return -EINVAL; + + hvc_desc->kvm_std_hyp_bmap = val; + return 0; default: return -ENOENT; } diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c index 78a09f7a6637..4fa436dbd0b7 100644 --- a/arch/arm64/kvm/pvtime.c +++ b/arch/arm64/kvm/pvtime.c @@ -37,6 +37,9 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu) u32 feature = smccc_get_arg1(vcpu); long val = SMCCC_RET_NOT_SUPPORTED; + if (!kvm_hvc_call_supported(vcpu, feature)) + return val; + switch (feature) { case ARM_SMCCC_HV_PV_TIME_FEATURES: case ARM_SMCCC_HV_PV_TIME_ST: diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index 5f01bb139312..bbb3b12b10e3 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -9,6 +9,9 @@ #define ARM_SMCCC_STD_FEATURES \ GENMASK_ULL(KVM_REG_ARM_STD_BMAP_MAX - 1, 0) +#define ARM_SMCCC_STD_HYP_FEATURES \ + GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0) + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); static inline u32 smccc_get_function(struct kvm_vcpu *vcpu) From patchwork Tue Nov 2 00:22:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597647 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 C1EA8C433EF for ; Tue, 2 Nov 2021 00:25:16 +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 8738260EDF for ; Tue, 2 Nov 2021 00:25:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 8738260EDF 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=a5AxQiRY/ujBvFIWUzKm3QpMD8vWl/MM/qx8DKuw9rg=; b=lCd686xK14Oa6vpsrEBgVdp3a/ I2U3FJOgTGEd4LlHZYgfYXkcYCDAzG0AEuSlH0AhytDgN7H+8jbdcW5ekn8nyfD5pt552+M77j40R bc17ocBdNekUT18bWawXexddHNYZOHdjNsabycdBYW1BkY1tVyZDXN0fuF/Q5UpieiNeQRseP4yRA 9ILXaXXbEy3vQxs6PDrs8iq/yMeZSDijVcUeD7I6nmzA6Oe5j83vZH+qImuwLglYuhrcQDfdQrZgN 89kpxPXnDSPP/UWXm8IZe3Zdqa7lVHyyGbEPr1X7geaZZNHLVdf7RT3W8NjRizgzV4gDpz0uQsdPv PQwoNbOg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhaa-0005OD-Cm; Tue, 02 Nov 2021 00:23:45 +0000 Received: from mail-pl1-x649.google.com ([2607:f8b0:4864:20::649]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZT-0004u5-TT for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:37 +0000 Received: by mail-pl1-x649.google.com with SMTP id g20-20020a170902869400b0014002b0f5bcso6750623plo.18 for ; Mon, 01 Nov 2021 17:22:34 -0700 (PDT) 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=NALAGHmxgx7zuM8oyYfEDkoub9zJsPFlJRLUtFgIAck=; b=dXWtApxl5gms1qPPG0RVxQ4mq3haQMJYuvojtTHjOAjrTjsHziwnuK9plCsnKpWYVK JVagrS4mCfUPLaDZIRdLVhOFH8VtH6y43Q07MBDa3oO7wH+cBSQJLf2hurHjBafft4Fs nA13INkYsaF1gPiDnKfRzfJlxH3uvIGN3uiDbeLwJIiZ7hcoSlCXjIaRUb7HzDiZ0+Dd NMQVVssXCWPf9RQHmqZpgBjUdgo/N/plL6ZYSngz8s1tK3K5WTVrjKyo5U+W/x14b8cy vwpfRUGfET93FmfJstu/401TocpsqlfCk6GMwJWaukKUBQ/6vqHLfkW3yaNtzRL0P1Pk DlMw== 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=NALAGHmxgx7zuM8oyYfEDkoub9zJsPFlJRLUtFgIAck=; b=7ONaIBizvDv0+Pvoux50L7aTdjCB1GfeZ7Cdi65bWRPhsvoCQ/xFqf7G+tSt/LBArQ FHL9l3KgUrxAqP6t2VLoHL9DixMiFgI8Acb5s5+064Jbkz2iB37Zxr68EBjZxSvhXgqg GyZwnXPS0/ZKvNJPZQ6woDyySMgY0hAl63is/V807tsHwsLVl+aIUeq4mq1BvjeOj0NU +H0JQcR3+/2C0Hfl3eyFC5VOkFhdVm11Qt+e9+hGtyfJu68of+j8YmHCqMNgfY1C3Lsw gttRk21fYjA1GR6WGvPE7Vh88SJWluKnV2Pk15Ifl1AKeMzmPpoZhmABJsBMHNdgqLYC WATA== X-Gm-Message-State: AOAM5308uldekDahZO1bJ0Pp9dQV5FTm2Q/Kf7+RKcAz07KvzOec9BMB RDjAGunjlBHQ3hLni22rw5ap51RmZtgn X-Google-Smtp-Source: ABdhPJwMfnQu9lzOq3lchz+AtyDKvVv2NetvtywLAd6UERBeOKB19I65Sh2KO1yOdv3p5euteXTMrxI6QPUZ X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6a00:13aa:b0:481:22b8:ba7a with SMTP id t42-20020a056a0013aa00b0048122b8ba7amr1347930pfg.28.1635812554109; Mon, 01 Nov 2021 17:22:34 -0700 (PDT) Date: Tue, 2 Nov 2021 00:22:00 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-6-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 5/8] KVM: arm64: Add vendor hypervisor service calls firmware register From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172235_991392_20A7BD5A X-CRM114-Status: GOOD ( 21.24 ) 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 Introduce the firmware register to hold the vendor specific hypervisor service calls (owner value 6) as a bitmap. The bitmap represents the features that'll be enabled for the guest, as configured by the user-space. Currently, this includes support only for Precision Time Protocol (PTP), represented by bit-0. Signed-off-by: Raghavendra Rao Ananta --- Documentation/virt/kvm/arm/hypercalls.rst | 23 +++++++++++----- arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/include/uapi/asm/kvm.h | 6 +++++ arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/hypercalls.c | 33 ++++++++++++++++++++++- include/kvm/arm_hypercalls.h | 3 +++ 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt/kvm/arm/hypercalls.rst index 2cb82c694868..61d95f4f1ddf 100644 --- a/Documentation/virt/kvm/arm/hypercalls.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -20,13 +20,14 @@ pseudo-registers" that can be manipulated using the GET/SET_ONE_REG interface. These registers can be saved/restored by userspace, and set to a convenient value if required. -The firmware registers, KVM_REG_ARM_STD and KVM_REG_ARM_STD_HYP exposes -the hypercall services in the form of a feature bitmap. Upon VM creation, -by default, KVM exposes all the features to the guest, which can be learnt -using GET_ONE_REG interface. Conversely, the features can be enabled or -disabled via the SET_ONE_REG interface. These registers allow the user-space -modification only until the VM has started running, after which they turn to -read-only registers. SET_ONE_REG in this scenario will return -EBUSY. +The firmware registers, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP and +KVM_REG_ARM_VENDOR_HYP exposes the hypercall services in the form of a +feature bitmap. Upon VM creation, by default, KVM exposes all the features +to the guest, which can be learnt using GET_ONE_REG interface. Conversely, +the features can be enabled or disabled via the SET_ONE_REG interface. +These registers allow the user-space modification only until the VM has +started running, after which they turn to read-only registers. +SET_ONE_REG in this scenario will return -EBUSY. The following register is defined: @@ -100,4 +101,12 @@ The following register is defined: The bit represents the Paravirtualized Time service (also known as stolen time) as represented by ARM DEN0057A. +* KVM_REG_ARM_VENDOR_HYP + Controls the bitmap of the Vendor specific Hypervisor Service Calls. + + The following bits are accepted: + + KVM_REG_ARM_STD_HYP_PTP: + The bit represents the Precision Time Protocol KVM service. + .. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index cee4f4b8a756..27861b3bd25f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -108,6 +108,7 @@ struct hvc_reg_desc { u64 kvm_std_bmap; u64 kvm_std_hyp_bmap; + u64 kvm_vendor_hyp_bmap; }; struct kvm_arch { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 46701da1a27d..a1d0e8e69eed 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -293,6 +293,12 @@ enum kvm_reg_arm_std_hyp_bmap { KVM_REG_ARM_STD_HYP_BMAP_MAX, }; +#define KVM_REG_ARM_VENDOR_HYP KVM_REG_ARM_FW_REG(5) +enum kvm_reg_arm_vendor_hyp_bmap { + KVM_REG_ARM_VENDOR_HYP_PTP, + KVM_REG_ARM_VENDOR_HYP_BMAP_MAX, +}; + /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 1c69d2a71b86..5c89db8336eb 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -136,6 +136,7 @@ static void set_default_hypercalls(struct kvm *kvm) hvc_desc->kvm_std_bmap = ARM_SMCCC_STD_FEATURES; hvc_desc->kvm_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES; + hvc_desc->kvm_vendor_hyp_bmap = ARM_SMCCC_VENDOR_HYP_FEATURES; } /** diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 46064c515058..74ebe5355dc0 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -67,6 +67,8 @@ static u64 *kvm_fw_reg_to_bmap(struct kvm *kvm, u64 fw_reg) return &hvc_desc->kvm_std_bmap; case KVM_REG_ARM_STD_HYP: return &hvc_desc->kvm_std_hyp_bmap; + case KVM_REG_ARM_VENDOR_HYP: + return &hvc_desc->kvm_vendor_hyp_bmap; default: return NULL; } @@ -93,6 +95,10 @@ static const struct kvm_hvc_func_map hvc_std_hyp_map[] = { HVC_FUNC_MAP_DESC(ARM_SMCCC_HV_PV_TIME_ST, KVM_REG_ARM_STD_HYP_PV_TIME_ST), }; +static const struct kvm_hvc_func_map hvc_vendor_hyp_map[] = { + HVC_FUNC_MAP_DESC(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_REG_ARM_VENDOR_HYP_PTP), +}; + bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) { struct kvm *kvm = vcpu->kvm; @@ -113,6 +119,11 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) hvc_func_map = hvc_std_hyp_map; map_sz = ARRAY_SIZE(hvc_std_hyp_map); break; + case ARM_SMCCC_OWNER_VENDOR_HYP: + fw_reg = KVM_REG_ARM_VENDOR_HYP; + hvc_func_map = hvc_vendor_hyp_map; + map_sz = ARRAY_SIZE(hvc_vendor_hyp_map); + break; default: /* Allow all the owners that aren't mapped */ return true; @@ -133,6 +144,7 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id) int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { + struct hvc_reg_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc; u32 func_id = smccc_get_function(vcpu); u64 val[4] = {SMCCC_RET_NOT_SUPPORTED}; u32 feature; @@ -204,7 +216,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) break; case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES); - val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP); + + /* + * The feature bits exposed to user-space doesn't include + * ARM_SMCCC_KVM_FUNC_FEATURES. However, we expose this to + * the guest as bit-0. Hence, left-shift the user-space + * exposed bitmap by 1 to accommodate this. + */ + val[0] |= (hvc_desc->kvm_vendor_hyp_bmap << 1); break; case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: kvm_ptp_get_time(vcpu, val); @@ -230,6 +249,7 @@ static const u64 fw_reg_ids[] = { KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP, + KVM_REG_ARM_VENDOR_HYP, }; int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) @@ -310,6 +330,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) case KVM_REG_ARM_STD_HYP: val = hvc_desc->kvm_std_hyp_bmap; break; + case KVM_REG_ARM_VENDOR_HYP: + val = hvc_desc->kvm_vendor_hyp_bmap; + break; default: return -ENOENT; } @@ -446,6 +469,14 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) hvc_desc->kvm_std_hyp_bmap = val; return 0; + + case KVM_REG_ARM_VENDOR_HYP: + if (val & ~ARM_SMCCC_VENDOR_HYP_FEATURES) + return -EINVAL; + + hvc_desc->kvm_vendor_hyp_bmap = val; + return 0; + default: return -ENOENT; } diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index bbb3b12b10e3..d8c17d161ee5 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -12,6 +12,9 @@ #define ARM_SMCCC_STD_HYP_FEATURES \ GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_MAX - 1, 0) +#define ARM_SMCCC_VENDOR_HYP_FEATURES \ + GENMASK_ULL(KVM_REG_ARM_VENDOR_HYP_BMAP_MAX - 1, 0) + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); static inline u32 smccc_get_function(struct kvm_vcpu *vcpu) From patchwork Tue Nov 2 00:22:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597649 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 4ABB0C433F5 for ; Tue, 2 Nov 2021 00:25:48 +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 17CA160EDF for ; Tue, 2 Nov 2021 00:25:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 17CA160EDF 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=1NIwgDB3oDRswm6y4d7sVDnmg98WUf0+wwTqOjzBS04=; b=oiqPBDt76rXvzbCTkk+6lgtd7D ZsEHTHBXO9qyCkmYo99RRj6rG/Knub0ShVlWff4o0t8PCQa2L1E6hgdAH7RoR6zDpMbJp4skKE/W6 tibOkQAyGisHuqGboGnN/xYaXeNJm8yAqTWKx2l/FS+/YjNxZHRWN+Kj9t5DJdI1e+jnxgP7vQHGB T2GDueWfssjxdZzGYDDKVROhiIluMnSN2qs8uFhf7V0XS6PKq2mmQyp38s/SzZZXhoadFnCNg4H8s a0k6gTuLzeSzaj7r/fuOJViBiroR54TBeg+LG2x8CD2/aEoWjby/WwokCT8i2AeN/Q4EqotX4Lef5 z7UGQkPg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhb8-0005fA-Qi; Tue, 02 Nov 2021 00:24:19 +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 1mhhZW-0004v0-H7 for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:39 +0000 Received: by mail-pf1-x449.google.com with SMTP id s22-20020a056a0008d600b00480fea2e96cso2995714pfu.7 for ; Mon, 01 Nov 2021 17:22:37 -0700 (PDT) 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=q8+WFsVbgm29AAf/AGwas77W0K8xwgbmPl1Tstb7QWc=; b=b7OJ80GPH2oQgQ9tb2V+6/eW0GWKJVLr1PWxB8v4wFAwbzrU4pUgP2cI0Riz7azO5G Z+6rcFj7+griGUkir/2Gug4bGdUYN2p9f39RS0Ie9f5uSe6HaSA/mFLmkPgf2GQpbG0d 5Uj2XEj05Mj2qzm0yYL9Dk4pz0EAn5W63XS6fNeOr6NTWCR/dHkpIRmXhIJtQkan6y6X /fqFwxj9iuYkiqbKxdWhd3ZvXyHvUTgQJa4OqwCSyt0QI4PWOnfljN5xnAgMSEk27aTJ kZ/8kU5lGgkp1PHOP2Rmza2Vvq/QL7beU+QmLk/l2Gi6o3hXyrVojRzFmnd0YUwtPd1I W03Q== 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=q8+WFsVbgm29AAf/AGwas77W0K8xwgbmPl1Tstb7QWc=; b=6X4dyz9McWSj39VcU3+Ql2yxOKH6glme0pOIQEAT6QI6oeKSlovKJc9sO9iHVwetkV FIAlEtPKrul3tnUGMDijvlY/zl8decZ4tj97qSOfTVXAgT5DYQTrS1gc7IyPrWwfIJxr t9IqE/oHoZ25je8ZSrw0MsT9ssgCQlf6ddvhqAoa61Bp+4z6gtU0k1GmxdebYHOlXNS+ 9JiZx+mRgkfRzXtHCk+dr7q4qBsiinAL44tGH8D+CE2V/ORsy98gZWSV7TqKx6C/5rSH PMeK02pl28ZYD1vj7X4oBC3wEDWhChsYaUF7j7lNQ9PaFyzZj2gUaADu4x5iQUZJuxnb 4YkA== X-Gm-Message-State: AOAM533O2ELyd4INxBond+oKWOc7UWDhPzAOXibFcOT9Z5O9ImEBp+66 ELxENC/OKr3lowAe8HatBqHUOYDVnsxx X-Google-Smtp-Source: ABdhPJwek5nlon1tiWB/vxBvYaoxxIt+RqFeK0GQlOxIF29WacF2NwA+ysmja9uIeRDDlLhNWR7SRXVq/jT7 X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90a:4a82:: with SMTP id f2mr2615207pjh.236.1635812556766; Mon, 01 Nov 2021 17:22:36 -0700 (PDT) Date: Tue, 2 Nov 2021 00:22:01 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-7-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 6/8] tools: Import the firmware registers From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172238_602670_40189E70 X-CRM114-Status: UNSURE ( 9.90 ) X-CRM114-Notice: Please train this message. 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 Import the firmware definitions for the firmware registers, KVM_REG_ARM_STD, KVM_REG_ARM_STD_HYP, and KVM_REG_ARM_VENDOR_HYP. Signed-off-by: Raghavendra Rao Ananta --- tools/arch/arm64/include/uapi/asm/kvm.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index b3edde68bc3e..a1d0e8e69eed 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -281,6 +281,24 @@ struct kvm_arm_copy_mte_tags { #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) +#define KVM_REG_ARM_STD KVM_REG_ARM_FW_REG(3) +enum kvm_reg_arm_std_bmap { + KVM_REG_ARM_STD_TRNG_V1_0, + KVM_REG_ARM_STD_BMAP_MAX, +}; + +#define KVM_REG_ARM_STD_HYP KVM_REG_ARM_FW_REG(4) +enum kvm_reg_arm_std_hyp_bmap { + KVM_REG_ARM_STD_HYP_PV_TIME_ST, + KVM_REG_ARM_STD_HYP_BMAP_MAX, +}; + +#define KVM_REG_ARM_VENDOR_HYP KVM_REG_ARM_FW_REG(5) +enum kvm_reg_arm_vendor_hyp_bmap { + KVM_REG_ARM_VENDOR_HYP_PTP, + KVM_REG_ARM_VENDOR_HYP_BMAP_MAX, +}; + /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) From patchwork Tue Nov 2 00:22:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597651 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 3008EC433EF for ; Tue, 2 Nov 2021 00:26:29 +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 E9B1C60FC4 for ; Tue, 2 Nov 2021 00:26:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E9B1C60FC4 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=mXGJIlC/ahY0qOs1wmIuMD3NARvF5dK25zMZCU8+XJo=; b=kkft39eKKrMPx1b/oXxMfCkPts mkw4324TdLnUubGnJWiEMWgnkXZGUEmLq15Y4k0M/2KdOdz/G623ZbIn/MUhWtpobl02g14aTF3dA /1icCqd/BmlMUacG1NwftMqMzQPJ5s7p60Vyt3HyXX4LsEiS6DanX56/YQY7gV66JEwV7fbSPHKjs X7HIlsX3V8IasOdf+wdP1tCXdvsBanTIoEvQlHxfYgrhEEMaaJsgiYVG9VHq8G2CdQdjGP84edg9N W+DG2t0SerLrw/hJ5xHP8p0CoKu16LE42cCfHZN9lutQpaGZsSMkznIjBf2KSxhNJm158FjgEJR9N URqds7LA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhbj-0005yu-8w; Tue, 02 Nov 2021 00:24:56 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZY-0004w2-CN for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:42 +0000 Received: by mail-pf1-x44a.google.com with SMTP id o202-20020a6292d3000000b00480ffe3c3baso2982006pfd.12 for ; Mon, 01 Nov 2021 17:22:39 -0700 (PDT) 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=oQnGvCOz4keJ5+U570faF9qbS7l4l0LO2nLR5m1MmaE=; b=CWf2Hnim1EskvJDGUXc6qWNnfMAazju3skN9odfbsYVloEo8BbNmtCPxtsnlCxRWss s5dYxk4Qft+iucKSSpW322aHL9FeajQAFVQTMxcGW02vHYlgxEhu+vkrJe77Zb2ugRwr tBKjAic300xT/K/OzvTIVaHEsJmLPrCd5zDoT3wxR+5hcAK0D9bBD6zNEuFeHM8BgHGh c8nGGNQGhYUiCqEdgPlVSe5ij6SEKj0azoSTSYFR+y2DkaHJNQTqpBKgY4TBFfrbfMXk p/TK1q3ywu6w6aDJgDXW8TML0trlBUmb9FfYpmtbzeC279iB0XQbKICbqeMD9eHOyXKZ IvdQ== 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=oQnGvCOz4keJ5+U570faF9qbS7l4l0LO2nLR5m1MmaE=; b=rHVKV6IxSkQy8VMuAKBIq0NGoWPubazQ+EdFzfL9MiDK+PUySjvvoMXIO9DLfew8Ha Qtbk8lBDa7VXXKMbeVpp57wqiXzjZ7OfWrtIJhQc4enxjW4CUOD8tPFgorkQ4ibebd+r 3fqu8lO9zmPYRauebjDSHTwuvhgDA74Bgl7JMtlMRuxR3mkLuCOxIpLd/I/+9kxHOn0Q uZv73kY4WHxJGUeQroWB+CD7mHfHHXc5IuELYBCAAP1ZkHIlqYIHIos4YoM0nkgbXdCv TLE24XPxHP+4LUbasDEccmeLo6cSNiHnNv+TrU9xz+oX5DNdZjY3/yfZVHE9V/rlq1nh Q/Zw== X-Gm-Message-State: AOAM5320qV68i6u0zVosJ2kO8AWHX1nF3tQy504d081VLRdGkQuK778t DABc4pBIKV/B2tF+YRnylfemstg1i5HI X-Google-Smtp-Source: ABdhPJyGvWZ7+T2rFxdjjiqc/GTxfjslCDUzKVpcszo/N2fFkYf47f8xeAQO6PAqD1XvebcAG8SZFRIirgU7 X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6a00:1a4c:b0:44b:1fa6:532c with SMTP id h12-20020a056a001a4c00b0044b1fa6532cmr32459984pfv.64.1635812559023; Mon, 01 Nov 2021 17:22:39 -0700 (PDT) Date: Tue, 2 Nov 2021 00:22:02 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-8-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 7/8] tools: Import ARM SMCCC definitions From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172240_459461_314EDDC5 X-CRM114-Status: GOOD ( 15.99 ) 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 Import the standard SMCCC definitions from include/linux/arm-smccc.h. Signed-off-by: Raghavendra Rao Ananta --- tools/include/linux/arm-smccc.h | 188 ++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 tools/include/linux/arm-smccc.h diff --git a/tools/include/linux/arm-smccc.h b/tools/include/linux/arm-smccc.h new file mode 100644 index 000000000000..e3a24ae6863a --- /dev/null +++ b/tools/include/linux/arm-smccc.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2015, Linaro Limited + */ +#ifndef __LINUX_ARM_SMCCC_H +#define __LINUX_ARM_SMCCC_H + +#include + +/* + * This file provides common defines for ARM SMC Calling Convention as + * specified in + * https://developer.arm.com/docs/den0028/latest + * + * This code is up-to-date with version DEN 0028 C + */ + +#define ARM_SMCCC_STD_CALL _AC(0,U) +#define ARM_SMCCC_FAST_CALL _AC(1,U) +#define ARM_SMCCC_TYPE_SHIFT 31 + +#define ARM_SMCCC_SMC_32 0 +#define ARM_SMCCC_SMC_64 1 +#define ARM_SMCCC_CALL_CONV_SHIFT 30 + +#define ARM_SMCCC_OWNER_MASK 0x3F +#define ARM_SMCCC_OWNER_SHIFT 24 + +#define ARM_SMCCC_FUNC_MASK 0xFFFF + +#define ARM_SMCCC_IS_FAST_CALL(smc_val) \ + ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT)) +#define ARM_SMCCC_IS_64(smc_val) \ + ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT)) +#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK) +#define ARM_SMCCC_OWNER_NUM(smc_val) \ + (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK) + +#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ + (((type) << ARM_SMCCC_TYPE_SHIFT) | \ + ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ + (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \ + ((func_num) & ARM_SMCCC_FUNC_MASK)) + +#define ARM_SMCCC_OWNER_ARCH 0 +#define ARM_SMCCC_OWNER_CPU 1 +#define ARM_SMCCC_OWNER_SIP 2 +#define ARM_SMCCC_OWNER_OEM 3 +#define ARM_SMCCC_OWNER_STANDARD 4 +#define ARM_SMCCC_OWNER_STANDARD_HYP 5 +#define ARM_SMCCC_OWNER_VENDOR_HYP 6 +#define ARM_SMCCC_OWNER_TRUSTED_APP 48 +#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 +#define ARM_SMCCC_OWNER_TRUSTED_OS 50 +#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 + +#define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01 + +#define ARM_SMCCC_QUIRK_NONE 0 +#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ + +#define ARM_SMCCC_VERSION_1_0 0x10000 +#define ARM_SMCCC_VERSION_1_1 0x10001 +#define ARM_SMCCC_VERSION_1_2 0x10002 +#define ARM_SMCCC_VERSION_1_3 0x10003 + +#define ARM_SMCCC_1_3_SVE_HINT 0x10000 + +#define ARM_SMCCC_VERSION_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0) + +#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 1) + +#define ARM_SMCCC_ARCH_SOC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 2) + +#define ARM_SMCCC_ARCH_WORKAROUND_1 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0x8000) + +#define ARM_SMCCC_ARCH_WORKAROUND_2 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0x7fff) + +#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_FUNC_QUERY_CALL_UID) + +/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */ +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 0xb66fb428U +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 0xe911c52eU +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 0x564bcaa9U +#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3 0x743a004dU + +/* KVM "vendor specific" services */ +#define ARM_SMCCC_KVM_FUNC_FEATURES 0 +#define ARM_SMCCC_KVM_FUNC_PTP 1 +#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 +#define ARM_SMCCC_KVM_NUM_FUNCS 128 + +#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_FEATURES) + +#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1 + +/* + * ptp_kvm is a feature used for time sync between vm and host. + * ptp_kvm module in guest kernel will get service from host using + * this hypercall ID. + */ +#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_PTP) + +/* ptp_kvm counter type ID */ +#define KVM_PTP_VIRT_COUNTER 0 +#define KVM_PTP_PHYS_COUNTER 1 + +/* Paravirtualised time calls (defined by ARM DEN0057A) */ +#define ARM_SMCCC_HV_PV_TIME_FEATURES \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD_HYP, \ + 0x20) + +#define ARM_SMCCC_HV_PV_TIME_ST \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD_HYP, \ + 0x21) + +/* TRNG entropy source calls (defined by ARM DEN0098) */ +#define ARM_SMCCC_TRNG_VERSION \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x50) + +#define ARM_SMCCC_TRNG_FEATURES \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x51) + +#define ARM_SMCCC_TRNG_GET_UUID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x52) + +#define ARM_SMCCC_TRNG_RND32 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x53) + +#define ARM_SMCCC_TRNG_RND64 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_STANDARD, \ + 0x53) + +/* + * Return codes defined in ARM DEN 0070A + * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C + */ +#define SMCCC_RET_SUCCESS 0 +#define SMCCC_RET_NOT_SUPPORTED -1 +#define SMCCC_RET_NOT_REQUIRED -2 +#define SMCCC_RET_INVALID_PARAMETER -3 + +#endif /*__LINUX_ARM_SMCCC_H*/ \ No newline at end of file From patchwork Tue Nov 2 00:22:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghavendra Rao Ananta X-Patchwork-Id: 12597653 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 AA48DC433F5 for ; Tue, 2 Nov 2021 00:27:00 +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 6BF4060FE8 for ; Tue, 2 Nov 2021 00:27:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6BF4060FE8 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=tVV7PapyUQoklbYPccMpds/eRqTg9ZFWtq5nZiX2Jsc=; b=tLIJeBBVef8W/yHiSaQuLLM7/S JtahuxAB0OyRxULUNvaEldM3QvK2yFJ3nA2g6n7ptaY0SGDQPsoNJbBJks+fYPw9xPJFdNQjWS5js GykmJgoiUpPQBuAXiQ39FWP5ZRmsaGvqe4szPCHCmOWSxIKMgNvRQZF/15Q785YTwKJzDuadYAITP vBj06zHnLQm2pcVwFUWc7Ex8/ORKhGn//1EUi0xUkuI54CV2TUOKb46ePyHjJtr4+orT12euD5N9v yAcdr610GTCJwmyX9Vmm4llXpfAch8oBZfsMZLOjTa1TFNw0jRhH3r0upuMy4TGRdvlyr/Zc+ncX8 YjajM6/w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhcK-0006HH-Pn; Tue, 02 Nov 2021 00:25:33 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mhhZa-0004x3-Mg for linux-arm-kernel@lists.infradead.org; Tue, 02 Nov 2021 00:22:44 +0000 Received: by mail-pl1-x64a.google.com with SMTP id o6-20020a170902778600b0013c8ce59005so6775020pll.2 for ; Mon, 01 Nov 2021 17:22:41 -0700 (PDT) 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=L+cvvbG+AbS6lwK44pG2+9XXxadBNUHbWgXFY0L4Kik=; b=UkDi3m3SRR+RutJX+DLcrQtrA6/5bnnlFoWL6RzF80faB3B3FaBqPYeEibCLqj0olG +S34TuL7R/9c9RWpWc0a55wrWa1jUIFNlolrcUvuc0ZudaVgn3U9V+VKY8LUGVaOefhE Rm1QSGONSydIUTw+BOipBYPAz6N1ZF28VwCkTnxE+U8xZSNQCHuEiCVbZYzk8lEqsh6D ojBTc6fnPBQ5ytsjHgyGnPUy3bYwd5+v5QkSY7rREHqQFoivCg7ztI69RjLVedMwyWJj TKeLrGMiEayLKBzDMtoYU6b3Tdi2QmA8kilNWQrTyke1igxWhto5c8jxiuQgRoLw1sys Qw5Q== 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=L+cvvbG+AbS6lwK44pG2+9XXxadBNUHbWgXFY0L4Kik=; b=XVzehG6WZ4MMuZ224Rz3EXXZ4m/SrxMXtL+Jh3kurTaqaf8rWlYMxOVB+2JJ3eNVFy 7S7darzwHNlf5lWJBnauAQ+bI0qnsubXvdPqr53Xr6miDOJY8BWgLTbCxmnkDh7r95wB 0WFgpIeYSgl1TD6yed39EDjEr3IP2MU41aNBsOrU7gYtw/wwQpjk5kvngiXThpFqULgq A8c4EoivF+5fCO3uMky/hF6iHNXNcruJcs/30YATpjIgUtvM8VbjAOXOkTqCrZGcyi3/ cHNOrLxaIzXn9aePOPUjtO5Uh3KgNcJT57LVt7gChlrMf9q9rydePjgbrWBaCo6V9QEq tXzg== X-Gm-Message-State: AOAM5327YIEXInX/q0oqf3TXZp6XWyA0qg+tqS3BJrGA6vpmDNJOioKC hrozPPfYRi3WZq0oDhDAuRWtxLV0DPxb X-Google-Smtp-Source: ABdhPJxfJF0pEwnq7m2SDK1WYpgrX79xXxzLJzvdVidDANpYkAF23OnhAWomc6Q06SgPN0ZhtNIRz+Enyq12 X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:aa7:8198:0:b0:44b:e191:7058 with SMTP id g24-20020aa78198000000b0044be1917058mr32989002pfi.39.1635812561476; Mon, 01 Nov 2021 17:22:41 -0700 (PDT) Date: Tue, 2 Nov 2021 00:22:03 +0000 In-Reply-To: <20211102002203.1046069-1-rananta@google.com> Message-Id: <20211102002203.1046069-9-rananta@google.com> Mime-Version: 1.0 References: <20211102002203.1046069-1-rananta@google.com> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog Subject: [RFC PATCH 8/8] selftests: KVM: aarch64: Introduce hypercall ABI test From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Catalin Marinas , Will Deacon , Peter Shier , Ricardo Koller , Oliver Upton , Reiji Watanabe , Jing Zhang , Raghavendra Rao Anata , linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org, kvm@vger.kernel.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211101_172242_788770_0DD9532C X-CRM114-Status: GOOD ( 23.74 ) 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 Introduce a KVM selftest to check the hypercall interface for arm64 platforms. The test validates the user-space's IOCTL interface to read/write the psuedo-firmware registers as well as its effects on the guest upon certain configurations. Signed-off-by: Raghavendra Rao Ananta --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/aarch64/hypercalls.c | 340 ++++++++++++++++++ 3 files changed, 342 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/hypercalls.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index 100d9a3a37f6..b56532fc3678 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -2,6 +2,7 @@ /aarch64/arch_timer /aarch64/debug-exceptions /aarch64/get-reg-list +/aarch64/hypercalls /aarch64/psci_test /aarch64/vgic_init /s390x/memop diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 8bcc8d1f226e..4b4aa75663bd 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -89,6 +89,7 @@ TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test TEST_GEN_PROGS_aarch64 += aarch64/arch_timer TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list +TEST_GEN_PROGS_aarch64 += aarch64/hypercalls TEST_GEN_PROGS_aarch64 += aarch64/psci_test TEST_GEN_PROGS_aarch64 += aarch64/vgic_init TEST_GEN_PROGS_aarch64 += demand_paging_test diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/aarch64/hypercalls.c new file mode 100644 index 000000000000..fa422769fcda --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include + +#include "processor.h" + +#define FW_REG_ULIMIT_VAL(max_feat_bit) (GENMASK_ULL(max_feat_bit, 0)) + +struct kvm_fw_reg_info { + uint64_t reg; /* Register definition */ + uint64_t max_feat_bit; /* Bit that represents the upper limit of the feature-map */ +}; + +#define FW_REG_INFO(r, bit_max) \ + { \ + .reg = r, \ + .max_feat_bit = bit_max, \ + } + +static const struct kvm_fw_reg_info fw_reg_info[] = { + FW_REG_INFO(KVM_REG_ARM_STD, KVM_REG_ARM_STD_BMAP_MAX - 1), + FW_REG_INFO(KVM_REG_ARM_STD_HYP, KVM_REG_ARM_STD_HYP_BMAP_MAX - 1), + FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP, KVM_REG_ARM_VENDOR_HYP_BMAP_MAX - 1), +}; + +enum test_stage { + TEST_STAGE_REG_IFACE, + TEST_STAGE_HVC_IFACE_FEAT_DISABLED, + TEST_STAGE_HVC_IFACE_FEAT_ENABLED, + TEST_STAGE_END, +}; + +static int stage; + +struct test_hvc_info { + uint32_t func_id; + int64_t arg0; + + void (*test_hvc_disabled)(const struct test_hvc_info *hc_info, + struct arm_smccc_res *res); + void (*test_hvc_enabled)(const struct test_hvc_info *hc_info, + struct arm_smccc_res *res); +}; + +#define TEST_HVC_INFO(f, a0, test_disabled, test_enabled) \ + { \ + .func_id = f, \ + .arg0 = a0, \ + .test_hvc_disabled = test_disabled, \ + .test_hvc_enabled = test_enabled, \ + } + +static void +test_ptp_feat_hvc_disabled(const struct test_hvc_info *hc_info, struct arm_smccc_res *res) +{ + GUEST_ASSERT_3((res->a0 & BIT(ARM_SMCCC_KVM_FUNC_PTP)) == 0, + res->a0, hc_info->func_id, hc_info->arg0); +} + +static void +test_ptp_feat_hvc_enabled(const struct test_hvc_info *hc_info, struct arm_smccc_res *res) +{ + GUEST_ASSERT_3((res->a0 & BIT(ARM_SMCCC_KVM_FUNC_PTP)) != 0, + res->a0, hc_info->func_id, hc_info->arg0); +} + +static const struct test_hvc_info hvc_info[] = { + /* KVM_REG_ARM_STD: KVM_REG_ARM_STD_TRNG_V1_0 */ + TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND64, NULL, NULL), + TEST_HVC_INFO(ARM_SMCCC_TRNG_GET_UUID, 0, NULL, NULL), + TEST_HVC_INFO(ARM_SMCCC_TRNG_RND32, 0, NULL, NULL), + TEST_HVC_INFO(ARM_SMCCC_TRNG_RND64, 0, NULL, NULL), + + /* KVM_REG_ARM_STD_HYP: PV_TIME */ + TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_HV_PV_TIME_ST, NULL, NULL), + TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_ST, 0, NULL, NULL), + + /* KVM_REG_ARM_VENDOR_HYP: PTP */ + TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID, + ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, + test_ptp_feat_hvc_disabled, test_ptp_feat_hvc_enabled), + TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, + KVM_PTP_VIRT_COUNTER, NULL, NULL), +}; + +static void guest_test_hvc(int stage) +{ + unsigned int i; + struct arm_smccc_res res; + + for (i = 0; i < ARRAY_SIZE(hvc_info); i++) { + const struct test_hvc_info *hc_info = &hvc_info[i]; + + memset(&res, 0, sizeof(res)); + smccc_hvc(hc_info->func_id, hc_info->arg0, 0, 0, 0, 0, 0, 0, &res); + + switch (stage) { + case TEST_STAGE_HVC_IFACE_FEAT_DISABLED: + if (hc_info->test_hvc_disabled) + hc_info->test_hvc_disabled(hc_info, &res); + else + GUEST_ASSERT_3(res.a0 == SMCCC_RET_NOT_SUPPORTED, + res.a0, hc_info->func_id, hc_info->arg0); + break; + case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: + if (hc_info->test_hvc_enabled) + hc_info->test_hvc_enabled(hc_info, &res); + else + GUEST_ASSERT_3(res.a0 != SMCCC_RET_NOT_SUPPORTED, + res.a0, hc_info->func_id, hc_info->arg0); + break; + default: + GUEST_ASSERT_1(0, stage); + } + } +} + +static void guest_code(void) +{ + while (stage != TEST_STAGE_END) { + switch (stage) { + case TEST_STAGE_REG_IFACE: + break; + case TEST_STAGE_HVC_IFACE_FEAT_DISABLED: + case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: + guest_test_hvc(stage); + break; + default: + GUEST_ASSERT_1(0, stage); + } + + GUEST_SYNC(stage); + } + + GUEST_DONE(); +} + +static int set_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t val) +{ + struct kvm_one_reg reg = { + .id = KVM_REG_ARM_FW_REG(id), + .addr = (uint64_t)&val, + }; + + return _vcpu_ioctl(vm, 0, KVM_SET_ONE_REG, ®); +} + +static void get_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t *addr) +{ + struct kvm_one_reg reg = { + .id = KVM_REG_ARM_FW_REG(id), + .addr = (uint64_t)addr, + }; + + return vcpu_ioctl(vm, 0, KVM_GET_ONE_REG, ®); +} + +struct st_time { + uint32_t rev; + uint32_t attr; + uint64_t st_time; +}; + +#define STEAL_TIME_SIZE ((sizeof(struct st_time) + 63) & ~63) +#define ST_GPA_BASE (1 << 30) + +static void steal_time_init(struct kvm_vm *vm) +{ + uint64_t st_ipa = (ulong)ST_GPA_BASE; + unsigned int gpages; + struct kvm_device_attr dev = { + .group = KVM_ARM_VCPU_PVTIME_CTRL, + .attr = KVM_ARM_VCPU_PVTIME_IPA, + .addr = (uint64_t)&st_ipa, + }; + + gpages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, STEAL_TIME_SIZE); + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, ST_GPA_BASE, 1, gpages, 0); + + vcpu_ioctl(vm, 0, KVM_SET_DEVICE_ATTR, &dev); +} + +static void test_fw_regs_before_vm_start(struct kvm_vm *vm) +{ + uint64_t val; + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) { + const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i]; + + /* First read should be an upper limit of the features supported */ + get_fw_reg(vm, reg_info->reg, &val); + TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), + "Expected all the features to be set for reg: 0x%lx; expected: 0x%llx; read: 0x%lx\n", + reg_info->reg, GENMASK_ULL(reg_info->max_feat_bit, 0), val); + } + + for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) { + const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i]; + + /* Test disabling all the features of the register map */ + ret = set_fw_reg(vm, reg_info->reg, 0); + TEST_ASSERT(ret == 0, + "Failed to clear all the features of reg: 0x%lx; ret: %d\n", + reg_info->reg, errno); + + get_fw_reg(vm, reg_info->reg, &val); + TEST_ASSERT(val == 0, + "Expected all the features to be cleared for reg: 0x%lx\n", reg_info->reg); + + /* Test enabling a feature that's not supported. Avoid this + * check if all the bits are occupied. + */ + if (reg_info->max_feat_bit < 63) { + ret = set_fw_reg(vm, reg_info->reg, BIT(reg_info->max_feat_bit + 1)); + TEST_ASSERT(ret != 0 && errno == EINVAL, + "Unexpected behavior or return value (%d) while setting an unsupported feature for reg: 0x%lx\n", + errno, reg_info->reg); + } + } +} + +static void test_fw_regs_after_vm_start(struct kvm_vm *vm) +{ + uint64_t val; + unsigned int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) { + const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i]; + + /* Before starting the VM, the test clears all the bits. + * Check if that's still the case. + */ + get_fw_reg(vm, reg_info->reg, &val); + TEST_ASSERT(val == 0, + "Expected all the features to be cleared for reg: 0x%lx\n", + reg_info->reg); + + /* Test setting the last known value. KVM should allow this + * even if VM has started running. + */ + ret = set_fw_reg(vm, reg_info->reg, 0); + TEST_ASSERT(ret == 0, + "Failed to clear all the features of reg: 0x%lx; ret: %d\n", + reg_info->reg, errno); + + /* Set all the features for this register again. KVM shouldn't + * allow this as the VM is running. + */ + ret = set_fw_reg(vm, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit)); + TEST_ASSERT(ret != 0 && errno == EBUSY, + "Unexpected behavior or return value (%d) while setting a feature while VM is running for reg: 0x%lx\n", + errno, reg_info->reg); + } +} + +static struct kvm_vm *test_vm_create(void) +{ + struct kvm_vm *vm; + + vm = vm_create_default(0, 0, guest_code); + + ucall_init(vm, NULL); + steal_time_init(vm); + + return vm; +} + +static struct kvm_vm *test_guest_stage(struct kvm_vm *vm) +{ + struct kvm_vm *ret_vm = vm; + + pr_debug("Stage: %d\n", stage); + + switch (stage) { + case TEST_STAGE_REG_IFACE: + test_fw_regs_after_vm_start(vm); + break; + case TEST_STAGE_HVC_IFACE_FEAT_DISABLED: + /* Start a new VM so that all the features are now enabled by default */ + kvm_vm_free(vm); + ret_vm = test_vm_create(); + break; + case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: + break; + default: + TEST_FAIL("Unknown test stage: %d\n", stage); + } + + stage++; + sync_global_to_guest(vm, stage); + + return ret_vm; +} + +static void test_run(void) +{ + struct kvm_vm *vm; + struct ucall uc; + bool guest_done = false; + + vm = test_vm_create(); + + test_fw_regs_before_vm_start(vm); + + while (!guest_done) { + vcpu_run(vm, 0); + + switch (get_ucall(vm, 0, &uc)) { + case UCALL_SYNC: + vm = test_guest_stage(vm); + break; + case UCALL_DONE: + guest_done = true; + break; + case UCALL_ABORT: + TEST_FAIL("%s at %s:%ld\n\tvalues: 0x%lx, %lu; %lu, stage: %u", + (const char *)uc.args[0], __FILE__, uc.args[1], + uc.args[2], uc.args[3], uc.args[4], stage); + break; + default: + TEST_FAIL("Unexpected guest exit\n"); + } + } + + kvm_vm_free(vm); +} + +int main(void) +{ + setbuf(stdout, NULL); + + test_run(); + return 0; +}