From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EB9FC4332F for ; Mon, 2 May 2022 23:40:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230178AbiEBXmt (ORCPT ); Mon, 2 May 2022 19:42:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229646AbiEBXmc (ORCPT ); Mon, 2 May 2022 19:42:32 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E1E73298F for ; Mon, 2 May 2022 16:39:00 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id b20-20020a62a114000000b0050a6280e374so8710069pff.13 for ; Mon, 02 May 2022 16:39:00 -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=CnvteBMbfF5gtOc3egqkMk6KG7PwGbNQiVe7F9DsL8s=; b=Yx6hwCRXLtgbZwuPX6/2Kelc7bkVTV7Nl746Zw3KzXdZmV5sLIbuEx7zDsTzGsGxhe rGyzYxLw/lHDjaVlxY1hs67bZ5TgdyiJa7Xga3NPxUrl5xVknQ6/cWN1/WjqiuPjDEP/ Hje0GZjeIs8tOcUZUfHxd2xYXKrrBWAuLqAO/9N5t3lHlJOQ5SQ5k+kZcOX5mRnema0a ELzGV+AZQWxkY38SfcFKKorK3JN8Dkc+5c7P8jPX999sUHF1HURpXjhs2qai+0T4ym1q LDmKl+RQbD9+0Ag3CW49ZLXlrKvpSREsM6SySxbEXWAaQ8AqePMc9yNQ3bt2sT7i0XPQ 3z8g== 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=CnvteBMbfF5gtOc3egqkMk6KG7PwGbNQiVe7F9DsL8s=; b=PCOGRl5o7qwwIjiT3nUdgmld1g4RSgOogvQwqMvDiK/TPOpSZ3wuiL9X30EovIQW3N emsngxMwe3fO6wl6fg7NuE8O/XrzJP08lp7EOWGjHpxBBSQH2brPPDGPFJLPaxYpvjWU 0y4Sup25Wfm00MaIhx3NKkV8R5eb7zfL2kZFYKgdXRJZ42ZpMPQ/hkEzREJB6xs3sOyG XUyDRHjRTgaq/KQLo6yVB62sdNM1PGVxdky11cfH98lGiYXmifUQfHZLPo0gis4wm5Qu r7c6kon6WiKmoIAcgCuhe9eVa17MBYp/6J4EkCIHQWd7VsrjGScVGmUVknCtd+xQc2uo yj9g== X-Gm-Message-State: AOAM5332NexTdlsyIMJ8tlm1Bt7pJ4zVARDQwfYPuHHl/vOJIjT9PQBC tevgWkZ8z8m//hXPxMHlDx006HkBzVrO X-Google-Smtp-Source: ABdhPJymKNe2h0UXH7Arc297B7IWUW4JzRKBItwjHsBM5F19dZ06kEhh3u50CiE22+1YXKoKfngWVEn5hDyo X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:902:6ac9:b0:156:a6ae:8806 with SMTP id i9-20020a1709026ac900b00156a6ae8806mr13756631plt.148.1651534739920; Mon, 02 May 2022 16:38:59 -0700 (PDT) Date: Mon, 2 May 2022 23:38:45 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-2-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 1/9] 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: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Also, define KVM_REG_FEATURE_LEVEL_MASK using a GENMASK instead. No functional change intended. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Oliver Upton Reviewed-by: Gavin Shan --- arch/arm64/kvm/guest.c | 2 +- arch/arm64/kvm/hypercalls.c | 185 +++++++++++++++++++++++++++++++++++ arch/arm64/kvm/psci.c | 183 ---------------------------------- include/kvm/arm_hypercalls.h | 7 ++ include/kvm/arm_psci.h | 7 -- 5 files changed, 193 insertions(+), 191 deletions(-) diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 7e15b03fbdf8..0d5cca56cbda 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 202b8c455724..fa6d9378d8e7 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -158,3 +158,188 @@ 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 kvm_arm_fw_reg_ids[] =3D { + KVM_REG_ARM_PSCI_VERSION, + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, + KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, +}; + +int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) +{ + return ARRAY_SIZE(kvm_arm_fw_reg_ids); +} + +int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindice= s) +{ + int i; + + for (i =3D 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) { + if (put_user(kvm_arm_fw_reg_ids[i], uindices++)) + return -EFAULT; + } + + return 0; +} + +#define KVM_REG_FEATURE_LEVEL_WIDTH 4 +#define KVM_REG_FEATURE_LEVEL_MASK GENMASK(KVM_REG_FEATURE_LEVEL_WIDTH, 0) + +/* + * Convert the workaround level into an easy-to-compare number, where high= er + * 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; + } + break; + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: + switch (arm64_get_spectre_bhb_state()) { + case SPECTRE_VULNERABLE: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; + case SPECTRE_MITIGATED: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL; + case SPECTRE_UNAFFECTED: + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED; + } + return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; + } + + return -EINVAL; +} + +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g) +{ + void __user *uaddr =3D (void __user *)(long)reg->addr; + u64 val; + + switch (reg->id) { + case KVM_REG_ARM_PSCI_VERSION: + val =3D kvm_psci_version(vcpu); + break; + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: + val =3D 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 *re= g) +{ + void __user *uaddr =3D (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 =3D 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 =3D val; + return 0; + case KVM_ARM_PSCI_0_2: + case KVM_ARM_PSCI_1_0: + case KVM_ARM_PSCI_1_1: + if (!wants_02) + return -EINVAL; + vcpu->kvm->arch.psci_version =3D val; + return 0; + } + break; + } + + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: + case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: + 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) !=3D KVM_REG_ARM_SMCCC_ARCH_WORKA= ROUND_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 =3D 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 =3D 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 708d80e8e60d..4bb76eb09248 100644 --- a/arch/arm64/kvm/psci.c +++ b/arch/arm64/kvm/psci.c @@ -437,186 +437,3 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) return -EINVAL; } } - -int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) -{ - return 4; /* PSCI version and three workaround registers */ -} - -int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindice= s) -{ - 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; - - if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, 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 high= er - * 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; - } - break; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: - switch (arm64_get_spectre_bhb_state()) { - case SPECTRE_VULNERABLE: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; - case SPECTRE_MITIGATED: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL; - case SPECTRE_UNAFFECTED: - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED; - } - return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL; - } - - return -EINVAL; -} - -int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g) -{ - void __user *uaddr =3D (void __user *)(long)reg->addr; - u64 val; - - switch (reg->id) { - case KVM_REG_ARM_PSCI_VERSION: - val =3D kvm_psci_version(vcpu); - break; - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: - val =3D 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 *re= g) -{ - void __user *uaddr =3D (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 =3D 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 =3D val; - return 0; - case KVM_ARM_PSCI_0_2: - case KVM_ARM_PSCI_1_0: - case KVM_ARM_PSCI_1_1: - if (!wants_02) - return -EINVAL; - vcpu->kvm->arch.psci_version =3D val; - return 0; - } - break; - } - - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: - case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: - 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) !=3D KVM_REG_ARM_SMCCC_ARCH_WORKA= ROUND_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 =3D 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 =3D 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/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 *vcp= u, vcpu_set_reg(vcpu, 3, a3); } =20 +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 *uindice= s); +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g); +int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g); + #endif diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h index 68b96c3826c3..6e55b9283789 100644 --- a/include/kvm/arm_psci.h +++ b/include/kvm/arm_psci.h @@ -39,11 +39,4 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu) =20 int kvm_psci_call(struct kvm_vcpu *vcpu); =20 -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 *uindice= s); -int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g); -int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g); - #endif /* __KVM_ARM_PSCI_H__ */ --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EDB91C4321E for ; Mon, 2 May 2022 23:40:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230392AbiEBXmw (ORCPT ); Mon, 2 May 2022 19:42:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229868AbiEBXme (ORCPT ); Mon, 2 May 2022 19:42:34 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4747F329A5 for ; Mon, 2 May 2022 16:39:02 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id r9-20020a17090aa08900b001d8826816e6so248636pjp.4 for ; Mon, 02 May 2022 16:39:02 -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=Erd91eBMxYL5RN3AW1Ampyw8AjL+yywAzXFIHsV7has=; b=j4bUvq3jLCvyiAae8u/L0aDPo5ei5h9yt1egJt3KHUWJrvEwoGdX9CYfar2lrhWPxK KE8xiTwOyo13xjU0NZUg9BOLw3BGcDTn1aU3a1Eo7pE1D8KcHj2cTigYz+oDBSb6mh7q /r5kj+wE5OO9eGQ6tPQRr9KbZZDZSeizmeE3SaR3ZKnY1RqcenR38upR8JDSGZ2MmVd3 1jKOWpp+v/wSekf1SayMSnqiKrB5Q6/WCYAjyFDeopdJ6tfX2poY1gUMqndJRUsWnqts Ka/QN7ZKSzaVxk6rcVritMz1+S5uJsL4ApYwJBFajUoDgDEdo66YHKeY1+mKveLosxKj 13Hw== 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=Erd91eBMxYL5RN3AW1Ampyw8AjL+yywAzXFIHsV7has=; b=YiznxtBxiqPbJDGFeBy7WYc4hQ6CjyegdNpidbFG8CB2yMgl+CNHiypqKtVwASkd6l lETDbVc2IoXJCPK7PvY4bA5dwcGbmIlTh4tsB6jzN7oDy5eJJKQ73rIag9Wn2QvhqEw5 /MSJcvrrVd1F1xw7Fd1lLPomJwd5W0zOlthkY7gKrNLAjP37nTa7RSfKldqYPSJFX2Bs 27tC64FFGOadZsFJjYtKyPKBRanuoD3mEZng45l1DXAeoEXPaz5/neFlzfwUqaGlotDv tu3TZzqPGdJrvmYYr4bvCgJtNZBehZf0A6GYIUyG9D+kdFdM9E624FC9rx46gS06BA9C KP7w== X-Gm-Message-State: AOAM530nbblJ5SlkvPxA+MnzDOInR5FEfP5N2Ex4VNcBytYonCw0liZC nm/E141No6pl/to5/PtaVqNIFIVenQ5P X-Google-Smtp-Source: ABdhPJzm0X+M89bexQ4/ThmDMbSorl28OooKgfEyVVRLAdp2t0A6SNYuY0igI1AglvM3CZaXh9FzV9vLelIg X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a62:ed0e:0:b0:4fa:11ed:2ad1 with SMTP id u14-20020a62ed0e000000b004fa11ed2ad1mr13310605pfh.34.1651534741653; Mon, 02 May 2022 16:39:01 -0700 (PDT) Date: Mon, 2 May 2022 23:38:46 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-3-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 2/9] KVM: arm64: Setup a framework for hypercall bitmap firmware registers From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" KVM regularly introduces new hypercall services to the guests without any consent from the userspace. This means, the guests can observe hypercall services in and out as they migrate across various host kernel versions. This could be a major problem if the guest discovered a hypercall, started using it, and after getting migrated to an older kernel realizes that it's no longer available. Depending on how the guest handles the change, there's a potential chance that the guest would just panic. As a result, there's a need for the userspace to elect the services that it wishes the guest to discover. It can elect these services based on the kernels spread across its (migration) fleet. To remedy this, extend the existing firmware pseudo-registers, such as KVM_REG_ARM_PSCI_VERSION, but by creating a new COPROC register space for all the hypercall services available. These firmware registers are categorized based on the service call owners, but unlike the existing firmware pseudo-registers, they hold the features supported in the form of a bitmap. During the VM initialization, the registers are set to upper-limit of the features supported by the corresponding registers. It's expected that the VMMs discover the features provided by each register via GET_ONE_REG, and write back the desired values using SET_ONE_REG. KVM allows this modification only until the VM has started. Some of the standard features are not mapped to any bits of the registers. But since they can recreate the original problem of making it available without userspace's consent, they need to be explicitly added to the case-list in kvm_hvc_call_default_allowed(). Any function-id that's not enabled via the bitmap, or not listed in kvm_hvc_call_default_allowed, will be returned as SMCCC_RET_NOT_SUPPORTED to the guest. Older userspace code can simply ignore the feature and the hypercall services will be exposed unconditionally to the guests, thus ensuring backward compatibility. In this patch, the framework adds the register only for ARM's standard secure services (owner value 4). 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. Other services are momentarily added in the upcoming patches. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 12 ++++ arch/arm64/include/uapi/asm/kvm.h | 9 +++ arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/guest.c | 8 ++- arch/arm64/kvm/hypercalls.c | 106 ++++++++++++++++++++++++++++++ arch/arm64/kvm/psci.c | 13 ++++ include/kvm/arm_hypercalls.h | 6 ++ include/kvm/arm_psci.h | 2 +- 8 files changed, 154 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 94a27a7520f4..fef597af0beb 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -101,6 +101,15 @@ struct kvm_s2_mmu { struct kvm_arch_memory_slot { }; =20 +/** + * struct kvm_smccc_features: Descriptor of the hypercall services exposed= to the guests + * + * @std_bmap: Bitmap of standard secure service calls + */ +struct kvm_smccc_features { + unsigned long std_bmap; +}; + struct kvm_arch { struct kvm_s2_mmu mmu; =20 @@ -150,6 +159,9 @@ struct kvm_arch { =20 u8 pfr0_csv2; u8 pfr0_csv3; + + /* Hypercall features firmware registers' descriptor */ + struct kvm_smccc_features smccc_feat; }; =20 struct kvm_vcpu_fault_info { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index c1b6ddc02d2f..0b79d2dc6ffd 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -332,6 +332,15 @@ struct kvm_arm_copy_mte_tags { #define KVM_ARM64_SVE_VLS_WORDS \ ((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1) =20 +/* Bitmap feature firmware registers */ +#define KVM_REG_ARM_FW_FEAT_BMAP (0x0016 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64= | \ + KVM_REG_ARM_FW_FEAT_BMAP | \ + ((r) & 0xffff)) + +#define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0) +#define KVM_REG_ARM_STD_BIT_TRNG_V1_0 0 + /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 523bc934fe2f..a37fadbd617e 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long typ= e) kvm->arch.max_vcpus =3D kvm_arm_default_max_vcpus(); =20 set_default_spectre(kvm); + kvm_arm_init_hypercalls(kvm); =20 return ret; out_free_stage2_pgd: diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 0d5cca56cbda..8c607199cad1 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -756,7 +756,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct= kvm_one_reg *reg) =20 switch (reg->id & KVM_REG_ARM_COPROC_MASK) { case KVM_REG_ARM_CORE: return get_core_reg(vcpu, reg); - case KVM_REG_ARM_FW: return kvm_arm_get_fw_reg(vcpu, reg); + case KVM_REG_ARM_FW: + case KVM_REG_ARM_FW_FEAT_BMAP: + return kvm_arm_get_fw_reg(vcpu, reg); case KVM_REG_ARM64_SVE: return get_sve_reg(vcpu, reg); } =20 @@ -774,7 +776,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct= kvm_one_reg *reg) =20 switch (reg->id & KVM_REG_ARM_COPROC_MASK) { case KVM_REG_ARM_CORE: return set_core_reg(vcpu, reg); - case KVM_REG_ARM_FW: return kvm_arm_set_fw_reg(vcpu, reg); + case KVM_REG_ARM_FW: + case KVM_REG_ARM_FW_FEAT_BMAP: + return kvm_arm_set_fw_reg(vcpu, reg); case KVM_REG_ARM64_SVE: return set_sve_reg(vcpu, reg); } =20 diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index fa6d9378d8e7..5c53fd1f5690 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -58,6 +58,48 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 = *val) val[3] =3D lower_32_bits(cycles); } =20 +static bool kvm_arm_fw_reg_feat_enabled(unsigned long *reg_bmap, unsigned = long feat_bit) +{ + return test_bit(feat_bit, reg_bmap); +} + +static bool kvm_hvc_call_default_allowed(u32 func_id) +{ + switch (func_id) { + /* + * List of function-ids that are not gated with the bitmapped feature + * firmware registers, and are to be allowed for servicing the call by de= fault. + */ + case ARM_SMCCC_VERSION_FUNC_ID: + case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: + case ARM_SMCCC_HV_PV_TIME_FEATURES: + case ARM_SMCCC_HV_PV_TIME_ST: + case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: + case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: + case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: + return true; + default: + return kvm_psci_func_id_is_valid(func_id); + } +} + +static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, u32 func_id) +{ + struct kvm_smccc_features *smccc_feat =3D &vcpu->kvm->arch.smccc_feat; + + switch (func_id) { + 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: + return kvm_arm_fw_reg_feat_enabled(&smccc_feat->std_bmap, + KVM_REG_ARM_STD_BIT_TRNG_V1_0); + default: + return kvm_hvc_call_default_allowed(func_id); + } +} + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { u32 func_id =3D smccc_get_function(vcpu); @@ -65,6 +107,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) u32 feature; gpa_t gpa; =20 + if (!kvm_hvc_call_allowed(vcpu, func_id)) + goto out; + switch (func_id) { case ARM_SMCCC_VERSION_FUNC_ID: val[0] =3D ARM_SMCCC_VERSION_1_1; @@ -155,6 +200,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) return kvm_psci_call(vcpu); } =20 +out: smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); return 1; } @@ -164,8 +210,16 @@ static const u64 kvm_arm_fw_reg_ids[] =3D { KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, + KVM_REG_ARM_STD_BMAP, }; =20 +void kvm_arm_init_hypercalls(struct kvm *kvm) +{ + struct kvm_smccc_features *smccc_feat =3D &kvm->arch.smccc_feat; + + smccc_feat->std_bmap =3D KVM_ARM_SMCCC_STD_FEATURES; +} + int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) { return ARRAY_SIZE(kvm_arm_fw_reg_ids); @@ -237,6 +291,7 @@ static int get_kernel_wa_level(u64 regid) =20 int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g) { + struct kvm_smccc_features *smccc_feat =3D &vcpu->kvm->arch.smccc_feat; void __user *uaddr =3D (void __user *)(long)reg->addr; u64 val; =20 @@ -249,6 +304,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: val =3D get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; break; + case KVM_REG_ARM_STD_BMAP: + val =3D READ_ONCE(smccc_feat->std_bmap); + break; default: return -ENOENT; } @@ -259,6 +317,52 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const st= ruct kvm_one_reg *reg) return 0; } =20 +static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 = val) +{ + int ret =3D 0; + struct kvm *kvm =3D vcpu->kvm; + struct kvm_smccc_features *smccc_feat =3D &kvm->arch.smccc_feat; + unsigned long *fw_reg_bmap, fw_reg_features; + + switch (reg_id) { + case KVM_REG_ARM_STD_BMAP: + fw_reg_bmap =3D &smccc_feat->std_bmap; + fw_reg_features =3D KVM_ARM_SMCCC_STD_FEATURES; + break; + default: + return -ENOENT; + } + + /* Check for unsupported bit */ + if (val & ~fw_reg_features) + return -EINVAL; + + /* + * Return -EBUSY if the VM (any vCPU) has already started running. + * + * To avoid unnecessary serialization of kvm->lock, check for + * KVM_ARCH_FLAG_HAS_RAN_ONCE, or if there's an update to the + * current bitmap's value, before grabbing the lock. + */ + if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags)) + return -EBUSY; + + if (val =3D=3D *fw_reg_bmap) + return 0; + + mutex_lock(&kvm->lock); + + if (test_bit(KVM_ARCH_FLAG_HAS_RAN_ONCE, &kvm->arch.flags)) { + ret =3D -EBUSY; + goto out; + } + + WRITE_ONCE(*fw_reg_bmap, val); +out: + mutex_unlock(&kvm->lock); + return ret; +} + int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g) { void __user *uaddr =3D (void __user *)(long)reg->addr; @@ -337,6 +441,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) return -EINVAL; =20 return 0; + case KVM_REG_ARM_STD_BMAP: + return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val); default: return -ENOENT; } diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c index 4bb76eb09248..94111f02674f 100644 --- a/arch/arm64/kvm/psci.c +++ b/arch/arm64/kvm/psci.c @@ -437,3 +437,16 @@ int kvm_psci_call(struct kvm_vcpu *vcpu) return -EINVAL; } } + +bool kvm_psci_func_id_is_valid(u32 func_id) +{ + if (ARM_SMCCC_OWNER_NUM(func_id) =3D=3D ARM_SMCCC_OWNER_STANDARD && + ARM_SMCCC_FUNC_NUM(func_id) >=3D 0 && ARM_SMCCC_FUNC_NUM(func_id) <=3D 0= x1f) + return true; + + /* KVM's PSCI 0.1 doesn't comply with SMCCC, and has its own function-id = base and range */ + if (func_id >=3D KVM_PSCI_FN(0) && func_id <=3D KVM_PSCI_FN(3)) + return true; + + return false; +} diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index 5d38628a8d04..c832e8411609 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -6,6 +6,11 @@ =20 #include =20 +/* Last valid bit of the bitmapped firmware registers */ +#define KVM_REG_ARM_STD_BMAP_BIT_MAX 0 + +#define KVM_ARM_SMCCC_STD_FEATURES GENMASK(KVM_REG_ARM_STD_BMAP_BIT_MAX, = 0) + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); =20 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu) @@ -42,6 +47,7 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu, =20 struct kvm_one_reg; =20 +void kvm_arm_init_hypercalls(struct kvm *kvm); int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu); int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindice= s); int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *re= g); diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h index 6e55b9283789..1f9ec5f2e513 100644 --- a/include/kvm/arm_psci.h +++ b/include/kvm/arm_psci.h @@ -36,7 +36,7 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu) return KVM_ARM_PSCI_0_1; } =20 - int kvm_psci_call(struct kvm_vcpu *vcpu); +bool kvm_psci_func_id_is_valid(u32 func_id); =20 #endif /* __KVM_ARM_PSCI_H__ */ --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D409C4167B for ; Mon, 2 May 2022 23:42:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231875AbiEBXov (ORCPT ); Mon, 2 May 2022 19:44:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229897AbiEBXme (ORCPT ); Mon, 2 May 2022 19:42:34 -0400 Received: from mail-pl1-x649.google.com (mail-pl1-x649.google.com [IPv6:2607:f8b0:4864:20::649]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB0B330569 for ; Mon, 2 May 2022 16:39:03 -0700 (PDT) Received: by mail-pl1-x649.google.com with SMTP id l5-20020a170902ec0500b0015cf1cfa4eeso7189434pld.17 for ; Mon, 02 May 2022 16:39:03 -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=2pS0hWgdcRkNq6G/AG55Sf0c4w4fc3fRzcRztfm+yWk=; b=GtU4SgSxO0cJLd7SyfV+bBd/e/2VdhxQkOfz8942QZ6RHqtRSA2C2b170+KQG0Ce01 ++WxiMfFdvz6EkBCG3NDgk2DCqwI/4W7NLZHvkdZE2WIujWVHYM9hhCDrOGhkU/SPa+L pfyoMyNCrMGHCND8hxqNCWACP4I9KguVW4dvn7eqLTEDHAdLaz4kBFh5oNv0Yy20Ybgm 7k7S6Wt/5C/6iF5iFGmWwx9HcwegPVEJ3kVf7UEx29aYPTciZQKrtSs1m/oLch5Ssz0m Kw9QE2Utj4pgNfEy1ZQxjkWqKnA3Em+UPFoSAYxOOTZJ074loWot3CSxX+AVn0uf9Arj 8vvg== 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=2pS0hWgdcRkNq6G/AG55Sf0c4w4fc3fRzcRztfm+yWk=; b=xhI5Ja+NPXcM8IBPOWB3n6hAaH8SM7ZtGQU+pA+ngtOHGOXJg8/9gv3LRzY8ktzu45 uLJVgxkGrnp3l4pRs8zOobKu7ombH1WKgA8kJjgf1WvY4aiag0cGN32cqOSKt7bK5p0a p9wr8cxoFXFlevbdTWnNShvPgkFTDga8KGux3mfBPf+Um4aFPKPJdfOT/rzo8lfDXbI0 JTuIWZLf0DVf3dV3qpHeuRwfE5WWkTBjq6tyCa3aMlcdmfisOfCM0QSmFxBf+xhypJhM SLr02nxYFnwW0wGDL07yLrdDFG0G0GISrOSs8moXl09YCStAJ8Eh+Ud5IzSpDRkETju/ BCaA== X-Gm-Message-State: AOAM533XjeeTD1r3ZwnGFm2Yas7HWmCrWWXmlyowRh0IJrAXVlm0gYFg T/pVJKNvr6owz0v07H75mBSQhEpaVQRE X-Google-Smtp-Source: ABdhPJwFb/AtX13N7sj14zodiD0VRVFe7aLDUk+R4QqXEYoR67zFerFbvOaWwX6sfpxIZlYCwfi+92NDbCt/ X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6a00:1a4d:b0:50d:5921:1a8f with SMTP id h13-20020a056a001a4d00b0050d59211a8fmr13347502pfv.64.1651534743200; Mon, 02 May 2022 16:39:03 -0700 (PDT) Date: Mon, 2 May 2022 23:38:47 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-4-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 3/9] KVM: arm64: Add standard hypervisor firmware register From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/include/uapi/asm/kvm.h | 3 +++ arch/arm64/kvm/hypercalls.c | 21 ++++++++++++++++++--- include/kvm/arm_hypercalls.h | 2 ++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index fef597af0beb..281dfcfd0a4e 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -105,9 +105,11 @@ struct kvm_arch_memory_slot { * struct kvm_smccc_features: Descriptor of the hypercall services exposed= to the guests * * @std_bmap: Bitmap of standard secure service calls + * @std_hyp_bmap: Bitmap of standard hypervisor service calls */ struct kvm_smccc_features { unsigned long std_bmap; + unsigned long std_hyp_bmap; }; =20 struct kvm_arch { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index 0b79d2dc6ffd..9eecc7ee8c14 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -341,6 +341,9 @@ struct kvm_arm_copy_mte_tags { #define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0) #define KVM_REG_ARM_STD_BIT_TRNG_V1_0 0 =20 +#define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1) +#define KVM_REG_ARM_STD_HYP_BIT_PV_TIME 0 + /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 5c53fd1f5690..38440e0bd4b4 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -72,8 +72,6 @@ static bool kvm_hvc_call_default_allowed(u32 func_id) */ case ARM_SMCCC_VERSION_FUNC_ID: case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: - case ARM_SMCCC_HV_PV_TIME_FEATURES: - case ARM_SMCCC_HV_PV_TIME_ST: case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: @@ -95,6 +93,10 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, = u32 func_id) case ARM_SMCCC_TRNG_RND64: return kvm_arm_fw_reg_feat_enabled(&smccc_feat->std_bmap, KVM_REG_ARM_STD_BIT_TRNG_V1_0); + case ARM_SMCCC_HV_PV_TIME_FEATURES: + case ARM_SMCCC_HV_PV_TIME_ST: + return kvm_arm_fw_reg_feat_enabled(&smccc_feat->std_hyp_bmap, + KVM_REG_ARM_STD_HYP_BIT_PV_TIME); default: return kvm_hvc_call_default_allowed(func_id); } @@ -102,6 +104,7 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu,= u32 func_id) =20 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { + struct kvm_smccc_features *smccc_feat =3D &vcpu->kvm->arch.smccc_feat; u32 func_id =3D smccc_get_function(vcpu); u64 val[4] =3D {SMCCC_RET_NOT_SUPPORTED}; u32 feature; @@ -165,7 +168,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) } break; case ARM_SMCCC_HV_PV_TIME_FEATURES: - val[0] =3D SMCCC_RET_SUCCESS; + if (kvm_arm_fw_reg_feat_enabled(&smccc_feat->std_hyp_bmap, + KVM_REG_ARM_STD_HYP_BIT_PV_TIME)) + val[0] =3D SMCCC_RET_SUCCESS; break; } break; @@ -211,6 +216,7 @@ static const u64 kvm_arm_fw_reg_ids[] =3D { KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, KVM_REG_ARM_STD_BMAP, + KVM_REG_ARM_STD_HYP_BMAP, }; =20 void kvm_arm_init_hypercalls(struct kvm *kvm) @@ -218,6 +224,7 @@ void kvm_arm_init_hypercalls(struct kvm *kvm) struct kvm_smccc_features *smccc_feat =3D &kvm->arch.smccc_feat; =20 smccc_feat->std_bmap =3D KVM_ARM_SMCCC_STD_FEATURES; + smccc_feat->std_hyp_bmap =3D KVM_ARM_SMCCC_STD_HYP_FEATURES; } =20 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) @@ -307,6 +314,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) case KVM_REG_ARM_STD_BMAP: val =3D READ_ONCE(smccc_feat->std_bmap); break; + case KVM_REG_ARM_STD_HYP_BMAP: + val =3D READ_ONCE(smccc_feat->std_hyp_bmap); + break; default: return -ENOENT; } @@ -329,6 +339,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vc= pu, u64 reg_id, u64 val) fw_reg_bmap =3D &smccc_feat->std_bmap; fw_reg_features =3D KVM_ARM_SMCCC_STD_FEATURES; break; + case KVM_REG_ARM_STD_HYP_BMAP: + fw_reg_bmap =3D &smccc_feat->std_hyp_bmap; + fw_reg_features =3D KVM_ARM_SMCCC_STD_HYP_FEATURES; + break; default: return -ENOENT; } @@ -442,6 +456,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) =20 return 0; case KVM_REG_ARM_STD_BMAP: + case KVM_REG_ARM_STD_HYP_BMAP: return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val); default: return -ENOENT; diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index c832e8411609..00f9f1b1dc16 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -8,8 +8,10 @@ =20 /* Last valid bit of the bitmapped firmware registers */ #define KVM_REG_ARM_STD_BMAP_BIT_MAX 0 +#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX 0 =20 #define KVM_ARM_SMCCC_STD_FEATURES GENMASK(KVM_REG_ARM_STD_BMAP_BIT_MAX, = 0) +#define KVM_ARM_SMCCC_STD_HYP_FEATURES GENMASK(KVM_REG_ARM_STD_HYP_BMAP_B= IT_MAX, 0) =20 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); =20 --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 096D3C43219 for ; Mon, 2 May 2022 23:40:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231139AbiEBXmy (ORCPT ); Mon, 2 May 2022 19:42:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229907AbiEBXmf (ORCPT ); Mon, 2 May 2022 19:42:35 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A108322BCF for ; Mon, 2 May 2022 16:39:05 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id l5-20020a170902ec0500b0015cf1cfa4eeso7189459pld.17 for ; Mon, 02 May 2022 16:39:05 -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=vCT/mW6tmMqNECNexsaejuEkL5/lGF6Ji7YYb+efIJc=; b=D8Qv8CrEKL7ZZJQl2WuZVKn3sCmfdpKTNUMPgq1yqfWDaAQGnZTO5mBwed9MGIDGD4 YI4lbC8LrGtIG6KqvO4w4m9LsAOpCXKsp0re2Jsxr9I5OIpmH+mjX9hRREj3V26zjAan MCzV5AmwUMlfnTGHIB+uGWgj03HgUaHisCZzj9hWTEuqLna+5IKbgeLDs3gpaF8HOgI+ JHz/0wIe3Z0IhUCZnjNtezQTZRnTfBhX+2Ihyz6RxdxgEVyfssG47bnlAE62QEzsADKX 9EE9DaInpTYezD0sS6tBmWJ+K0MIwOsPndiLeGs5+G1/9XuXzNpF/Cpylmq0Dyaq7JhH NnMA== 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=vCT/mW6tmMqNECNexsaejuEkL5/lGF6Ji7YYb+efIJc=; b=xlBLk1Ar9ovSufthZK6A8diTB0B0kXIlbKShAnhS5NRG4xp8H0BIVUOzVkQjRZ9bh8 J4290BULO43HRZbHu/SZzPbwjJP8i7Ru2Zt9pnlYqkQdAOXpKXD5+sND4LMtFZreIvhf d6lsZESJSS37zWN3BB6qElk4eKHQvdlUMpDtWgzsnYUjLHm24bJGtM3oZl+K8DPPPgtT 6IkD2782OQuZ3DgBgjlwxPzvKfI6NfV7MU6G4Mw+7wfCzNGvjtndnUMRhcVLKt3YsYyc 0ltkRsLbc9NJqrkfY1YkkO67XhAmQa9it+peEQtp3DsNUv89sLXDc7ykQok1o2DmzLSs P59Q== X-Gm-Message-State: AOAM5329yJwIalD0h6IhTbYXdZQFZrBh4yQqRaEf9r9RiZwMgUzSgZ8n 8Asb3DfnopUKfydzkFpfG61sFEjljfDu X-Google-Smtp-Source: ABdhPJzb8kwApWrNlqYhIjgtfeQtDRhDA6oB1Hw90FbM0L5E/ksrz7umT7RyvmjK2FYPtLmlM3VgUh49JZp+ X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:903:94:b0:15c:f928:a373 with SMTP id o20-20020a170903009400b0015cf928a373mr13992600pld.26.1651534745043; Mon, 02 May 2022 16:39:05 -0700 (PDT) Date: Mon, 2 May 2022 23:38:48 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-5-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 4/9] KVM: arm64: Add vendor hypervisor firmware register From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 for KVM-vendor features along with reading the UID, represented by bit-0, and Precision Time Protocol (PTP), represented by bit-1. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/include/uapi/asm/kvm.h | 4 ++++ arch/arm64/kvm/hypercalls.c | 23 ++++++++++++++++++----- include/kvm/arm_hypercalls.h | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 281dfcfd0a4e..35a60d766fba 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -106,10 +106,12 @@ struct kvm_arch_memory_slot { * * @std_bmap: Bitmap of standard secure service calls * @std_hyp_bmap: Bitmap of standard hypervisor service calls + * @vendor_hyp_bmap: Bitmap of vendor specific hypervisor service calls */ struct kvm_smccc_features { unsigned long std_bmap; unsigned long std_hyp_bmap; + unsigned long vendor_hyp_bmap; }; =20 struct kvm_arch { diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index 9eecc7ee8c14..e7d5ae222684 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -344,6 +344,10 @@ struct kvm_arm_copy_mte_tags { #define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1) #define KVM_REG_ARM_STD_HYP_BIT_PV_TIME 0 =20 +#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2) +#define KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT 0 +#define KVM_REG_ARM_VENDOR_HYP_BIT_PTP 1 + /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index 38440e0bd4b4..c4f2abd49e69 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -72,9 +72,6 @@ static bool kvm_hvc_call_default_allowed(u32 func_id) */ case ARM_SMCCC_VERSION_FUNC_ID: case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: - case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: - case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: - case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: return true; default: return kvm_psci_func_id_is_valid(func_id); @@ -97,6 +94,13 @@ static bool kvm_hvc_call_allowed(struct kvm_vcpu *vcpu, = u32 func_id) case ARM_SMCCC_HV_PV_TIME_ST: return kvm_arm_fw_reg_feat_enabled(&smccc_feat->std_hyp_bmap, KVM_REG_ARM_STD_HYP_BIT_PV_TIME); + case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: + case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: + return kvm_arm_fw_reg_feat_enabled(&smccc_feat->vendor_hyp_bmap, + KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT); + case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: + return kvm_arm_fw_reg_feat_enabled(&smccc_feat->vendor_hyp_bmap, + KVM_REG_ARM_VENDOR_HYP_BIT_PTP); default: return kvm_hvc_call_default_allowed(func_id); } @@ -189,8 +193,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) val[3] =3D ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3; break; case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: - val[0] =3D BIT(ARM_SMCCC_KVM_FUNC_FEATURES); - val[0] |=3D BIT(ARM_SMCCC_KVM_FUNC_PTP); + val[0] =3D smccc_feat->vendor_hyp_bmap; break; case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: kvm_ptp_get_time(vcpu, val); @@ -217,6 +220,7 @@ static const u64 kvm_arm_fw_reg_ids[] =3D { KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3, KVM_REG_ARM_STD_BMAP, KVM_REG_ARM_STD_HYP_BMAP, + KVM_REG_ARM_VENDOR_HYP_BMAP, }; =20 void kvm_arm_init_hypercalls(struct kvm *kvm) @@ -225,6 +229,7 @@ void kvm_arm_init_hypercalls(struct kvm *kvm) =20 smccc_feat->std_bmap =3D KVM_ARM_SMCCC_STD_FEATURES; smccc_feat->std_hyp_bmap =3D KVM_ARM_SMCCC_STD_HYP_FEATURES; + smccc_feat->vendor_hyp_bmap =3D KVM_ARM_SMCCC_VENDOR_HYP_FEATURES; } =20 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) @@ -317,6 +322,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) case KVM_REG_ARM_STD_HYP_BMAP: val =3D READ_ONCE(smccc_feat->std_hyp_bmap); break; + case KVM_REG_ARM_VENDOR_HYP_BMAP: + val =3D READ_ONCE(smccc_feat->vendor_hyp_bmap); + break; default: return -ENOENT; } @@ -343,6 +351,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vc= pu, u64 reg_id, u64 val) fw_reg_bmap =3D &smccc_feat->std_hyp_bmap; fw_reg_features =3D KVM_ARM_SMCCC_STD_HYP_FEATURES; break; + case KVM_REG_ARM_VENDOR_HYP_BMAP: + fw_reg_bmap =3D &smccc_feat->vendor_hyp_bmap; + fw_reg_features =3D KVM_ARM_SMCCC_VENDOR_HYP_FEATURES; + break; default: return -ENOENT; } @@ -457,6 +469,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const str= uct kvm_one_reg *reg) return 0; case KVM_REG_ARM_STD_BMAP: case KVM_REG_ARM_STD_HYP_BMAP: + case KVM_REG_ARM_VENDOR_HYP_BMAP: return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val); default: return -ENOENT; diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h index 00f9f1b1dc16..7d4d953680f7 100644 --- a/include/kvm/arm_hypercalls.h +++ b/include/kvm/arm_hypercalls.h @@ -9,9 +9,11 @@ /* Last valid bit of the bitmapped firmware registers */ #define KVM_REG_ARM_STD_BMAP_BIT_MAX 0 #define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX 0 +#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX 1 =20 #define KVM_ARM_SMCCC_STD_FEATURES GENMASK(KVM_REG_ARM_STD_BMAP_BIT_MAX, = 0) #define KVM_ARM_SMCCC_STD_HYP_FEATURES GENMASK(KVM_REG_ARM_STD_HYP_BMAP_B= IT_MAX, 0) +#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES GENMASK(KVM_REG_ARM_VENDOR_HYP_B= MAP_BIT_MAX, 0) =20 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); =20 --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EFC4C4167D for ; Mon, 2 May 2022 23:40:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231233AbiEBXm4 (ORCPT ); Mon, 2 May 2022 19:42:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229840AbiEBXmh (ORCPT ); Mon, 2 May 2022 19:42:37 -0400 Received: from mail-pf1-x44a.google.com (mail-pf1-x44a.google.com [IPv6:2607:f8b0:4864:20::44a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4AB9227FFC for ; Mon, 2 May 2022 16:39:07 -0700 (PDT) Received: by mail-pf1-x44a.google.com with SMTP id j8-20020aa78d08000000b0050ade744b37so8682473pfe.16 for ; Mon, 02 May 2022 16:39:07 -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=mpC3gngOJnTYNbZIy5XpBZE4tNfXvg4sSdGII/rINPg=; b=kwJzZU08zTMMYRTPGul44netZRFM/Fn7mp2jbTMXigZFZjwIWzKp7+vSa1nCB8qwgS kCbrRB58JNwK9MoOO12gCVsZ1DM+1nuUeA98O7urT8dIDnngCH704X7hz0NU8r1zvpat wcnNFYuTZ4XW1B6+wWWG43FqBL56s+0FTwQGVOOpie0v1F0ZphBbDiIoVstFw3HISQHo 0SuqofRCG5wZcjFZVbOcarkCL/9CBE0/mqvaXhokdaQJppOXdi/iIR2L2gpYpyzsDj1h lL4DO4OXCo4BSRFALMwUYoqFOLGiQueq4HT8CsYDiYofE9GPbh6PvRZTzCBd8Ujzg0PD /Zrg== 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=mpC3gngOJnTYNbZIy5XpBZE4tNfXvg4sSdGII/rINPg=; b=E9FLw2PxfBS3Az3wN3FoUt4FH+SQw4YXoPrjo3FtWI0GBPKpu8xYlUVZShcJWJsyHc fUxka+dnz5tzmWfWQ8TcEo9FFMKXedsBAu4uBH2Vu9sWsoppkElzzh1zVq3h0JjiqVmY 7WYx7+Dl/vyNmVNSlywpT8jY4FS9B9iXU9v+pz6nA69FpjiSlHddGrEAx2w8BwR96kkh rqFeCM6e7E+0AL60KjoZniFy+mfhwoUxB2/sHQgI6Rl2ym2RR1G5pfgeFXIvdgcR7dho Lim7J1sbLKTPsiU+mrNi13TnmxhsDlEb/LxmzrxLuM0kZw8atH8VWpZKOWChV4AH1+er 7G2g== X-Gm-Message-State: AOAM531tAKqlfkgQtI1L7vjfCbYzmvW2DE2EkiLRL7Qkv7vloopS7Vpd 84DBWModmDN0Us+sbU2K1I5aD1kFpCvn X-Google-Smtp-Source: ABdhPJyaZXXkFRI0DH02jQSgoTliFZw6c6KZBZFaTXiesw7Fo73NRrlthGbaEga6iWfIyzRxWO1La6dDWR5Z X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:902:d4d2:b0:15e:a9b0:3b21 with SMTP id o18-20020a170902d4d200b0015ea9b03b21mr5688864plg.142.1651534746776; Mon, 02 May 2022 16:39:06 -0700 (PDT) Date: Mon, 2 May 2022 23:38:49 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-6-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 5/9] Docs: KVM: Rename psci.rst to hypercalls.rst From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since the doc also covers general hypercalls' details, rather than just PSCI, and the fact that the bitmap firmware registers' details will be added to this doc, rename the file to a more appropriate name- hypercalls.rst. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- Documentation/virt/kvm/arm/{psci.rst =3D> hypercalls.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/virt/kvm/arm/{psci.rst =3D> hypercalls.rst} (100%) diff --git a/Documentation/virt/kvm/arm/psci.rst b/Documentation/virt/kvm/a= rm/hypercalls.rst similarity index 100% rename from Documentation/virt/kvm/arm/psci.rst rename to Documentation/virt/kvm/arm/hypercalls.rst --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D336C43219 for ; Mon, 2 May 2022 23:42:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231712AbiEBXoj (ORCPT ); Mon, 2 May 2022 19:44:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230016AbiEBXmj (ORCPT ); Mon, 2 May 2022 19:42:39 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1145822296 for ; Mon, 2 May 2022 16:39:08 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id i188-20020a636dc5000000b003c143f97bc2so7655297pgc.11 for ; Mon, 02 May 2022 16:39:08 -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=iAnIEZoxFvZcpUiI2JvanBeFHfSeSOkvmHvqJfm/zII=; b=letkbXX6ibxsOx6SG6cpYtGpVqlihTPUapx3VMOK3tKO5nMAIBqLmP1R+G/H79hn6z D3dMy9lOsmUparnWVrS/zBQGNU1jPkdufkUlSlviUeK8cCW8y1BUri6EcEsO3QUL1Kin VIfhpnmPpDR3HCldG9pOtTuNJYHbY8Yq2OeikN5FPLkimtJ4eAwI2sEFzielefJ+nTff wyLlslbL/YsXyh3mkmpb7mnhXDyQj+rv2EEduT2zFyTaWWvTG3Lm9nRibnhGRm0PBVkq gK6MBN3z7/19iXoFZoZkkCjCbAHHr4D49VJlbJ2A19at1ljCx7dIN3SdOswdbkJlmulr s3uA== 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=iAnIEZoxFvZcpUiI2JvanBeFHfSeSOkvmHvqJfm/zII=; b=AQMAJTLO1MQFNyMSYE3S7FctZjObJdoekiKeFWUc9Xnt3QLq/45DL1M+mhVcdT60Wb 8FP1I4s6Le+0qNLKc7zwOG+MlBTAPiQMFLOtxD2XF8fMKxLY3HemMP60V8sj8DxoNkrV gnDdPWXj6C4XCodgS7sNzDcXSZNVe3Xf7tI7dxhh/8JwRvnCcogV7UKmeIECrbwIcUG0 3PNmIXTUK8k7o/b8duuG8WnD21BRN3rlG8HjuWJH+sBroHJbAZiuPj2gVrHq0c7nRD9V 0nt6AMRtWoq+gomsLa0rOnCtGiUXY41bfr0+CFBRROCEGoZ12t738jHVzCMBZZg+2KkG MqCg== X-Gm-Message-State: AOAM530I0+gXpfnbwVT2UGEAI+kIu1o1PemZeztif9Qi/OMWNxHCv1O1 8RvtgxGsoakLsmJJAnxPlRpKr4bFVvVS X-Google-Smtp-Source: ABdhPJyXQR7muVhKAlvZ3f9QrEFalM+VA9iIEkI1MvgTnwrFA4Swlm7HbQmeqI8TiVM1t3D3hWJMl7T+c3MZ X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a17:90a:2e0d:b0:1c9:b839:af02 with SMTP id q13-20020a17090a2e0d00b001c9b839af02mr1691249pjd.122.1651534748316; Mon, 02 May 2022 16:39:08 -0700 (PDT) Date: Mon, 2 May 2022 23:38:50 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-7-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 6/9] Docs: KVM: Add doc for the bitmap firmware registers From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the documentation for the bitmap firmware registers in hypercalls.rst and api.rst. This includes the details for KVM_REG_ARM_STD_BMAP, KVM_REG_ARM_STD_HYP_BMAP, and KVM_REG_ARM_VENDOR_HYP_BMAP registers. Since the document is growing to carry other hypercall related information, make necessary adjustments to present the document in a generic sense, rather than being PSCI focused. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- Documentation/virt/kvm/api.rst | 16 ++++ Documentation/virt/kvm/arm/hypercalls.rst | 94 ++++++++++++++++++----- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 4a900cdbc62e..8ae638be79fd 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -2542,6 +2542,22 @@ arm64 firmware pseudo-registers have the following b= it pattern:: =20 0x6030 0000 0014 =20 +arm64 bitmap feature firmware pseudo-registers have the following bit patt= ern:: + + 0x6030 0000 0016 + +The bitmap feature firmware registers exposes the hypercall services that = are +available for userspace to configure. The set bits corresponds to the serv= ices +that are available for the guests to access. By default, KVM sets all the +supported bits during VM initialization. The userspace can discover the +available services via KVM_GET_ONE_REG, and write back the bitmap correspo= nding +to the features that it wishes guests to see via KVM_SET_ONE_REG. + +Note: These registers are immutable once any of the vCPUs of the VM has ru= n at +least once. A KVM_SET_ONE_REG in such a scenario will return a -EBUSY to u= serspace. + +(See Documentation/virt/kvm/arm/hypercalls.rst for more details.) + arm64 SVE registers have the following bit patterns:: =20 0x6080 0000 0015 00 Zn bits[2048*slice + 2047 : 2048*s= lice] diff --git a/Documentation/virt/kvm/arm/hypercalls.rst b/Documentation/virt= /kvm/arm/hypercalls.rst index d52c2e83b5b8..383ca766cf36 100644 --- a/Documentation/virt/kvm/arm/hypercalls.rst +++ b/Documentation/virt/kvm/arm/hypercalls.rst @@ -1,32 +1,32 @@ .. SPDX-License-Identifier: GPL-2.0 =20 -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -Power State Coordination Interface (PSCI) -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +ARM Hypercall Interface +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -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. +KVM handles the hypercall services as requested by the guests. New hyperca= ll +services are regularly made available by the ARM specification or by KVM (= as +vendor services) if they make sense from a virtualization point of view. =20 -The PSCI specification is regularly updated to provide new features, -and KVM implements these updates 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. +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 gue= st +is tied to a particular version of a hypercall service, or if a migration +causes a different version to be exposed out of the blue to an unsuspecting +guest. =20 In order to remedy this situation, KVM exposes a set of "firmware 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. +to a convenient value as required. =20 -The following register is defined: +The following registers are defined: =20 * KVM_REG_ARM_PSCI_VERSION: =20 + 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) - Returns the current PSCI version on GET_ONE_REG (defaulting to the @@ -74,4 +74,62 @@ 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. =20 -.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmw= are_interfaces_for_mitigating_CVE-2017-5715.pdf + +Bitmap Feature Firmware Registers +--------------------------------- + +Contrary to the above registers, the following registers exposes the hyper= call +services in the form of a feature-bitmap to the userspace. This bitmap is +translated to the services that are available to the guest. There is a reg= ister +defined per service call owner and can be accessed via GET/SET_ONE_REG int= erface. + +By default, these registers are set with the upper limit of the features t= hat +are supported. This way userspace can discover all the electable hypercall= services +via GET_ONE_REG. The user-space can write-back the desired bitmap back via +SET_ONE_REG. The features for the registers that are untouched, probably b= ecause +userspace isn't aware of them, will be exposed as is to the guest. + +Note that KVM would't allow the userspace to configure the registers anymo= re once +any of the vCPUs has run at least once. Instead, it will return a -EBUSY. + +The psuedo-firmware bitmap register are as follows: + +* KVM_REG_ARM_STD_BMAP: + Controls the bitmap of the ARM Standard Secure Service Calls. + + The following bits are accepted: + + Bit-0: KVM_REG_ARM_STD_BIT_TRNG_V1_0: + The bit represents the services offered under v1.0 of ARM True Random + Number Generator (TRNG) specification, ARM DEN0098. + +* KVM_REG_ARM_STD_HYP_BMAP: + Controls the bitmap of the ARM Standard Hypervisor Service Calls. + + The following bits are accepted: + + Bit-0: KVM_REG_ARM_STD_HYP_BIT_PV_TIME: + The bit represents the Paravirtualized Time service as represented by + ARM DEN0057A. + +* KVM_REG_ARM_VENDOR_HYP_BMAP: + Controls the bitmap of the Vendor specific Hypervisor Service Calls. + + The following bits are accepted: + + Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT + The bit represents the ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID + and ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID function-ids. + + Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP: + The bit represents the Precision Time Protocol KVM service. + +Errors: + + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + -ENOENT Unknown register accessed. + -EBUSY Attempt a 'write' to the register after the VM has started. + -EINVAL Invalid bitmap written to the register. + =3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmw= are_interfaces_for_mitigating_CVE-2017-5715.pdf \ No newline at end of file --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37149C4332F for ; Mon, 2 May 2022 23:42:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231421AbiEBXoc (ORCPT ); Mon, 2 May 2022 19:44:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230111AbiEBXmm (ORCPT ); Mon, 2 May 2022 19:42:42 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED48D3055E for ; Mon, 2 May 2022 16:39:10 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id t70-20020a638149000000b0039daafb0a84so5050436pgd.7 for ; Mon, 02 May 2022 16:39:10 -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=FAxBmKy8mhrk3+kWcYZem7wJzjSmZEXFa/bTuE7QCco=; b=SAhwsh9/Os5EDHGIo1Sr/pFRys6NYSp5x6iBk8nmnMD+BBrJsZ3HtvPpW0pdJWBFxS yrmO+wP9+LHHuk/tnlw3LWG/5FXC9kkMUa0nf2vP8USZkBeELEpzEc6Nlk91hRTZC/DA dJlptX3BIvXMgbAHzkhxCUMreO+dhSbzDjn/TMHPedernrnIkevXOXcG71p5CNG8XpyS WPz4fHybmlg0D2xlTFZ2b24mxlYUTFJthL1amQwDWhWKOOUzzLgYF5Xzl9RxVyCCNID0 ruLKLePwFqBLFq5r8hvJt2uTEQa2ifCB9q+Ac82bHZW3Cur/GdHmFVqKXQd4sBWFFJeC vsTg== 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=FAxBmKy8mhrk3+kWcYZem7wJzjSmZEXFa/bTuE7QCco=; b=VUlaMjCjHobpDb6OdnKYWj65gKNx6bP7mvFQrM7F1HRXrx61YH4aHWYzh1qnaaS2iB SPDdvBOrdN6uH57tJrcIs61nqV0ytAUc7nbu4QE2a1NSzt2Ebo0pIgrb3Xvp7zuuxWKk NcrG/qQX40LJF9jgsy0k9RrrfepOJfW6IljJICa8EA2E5rE9CKy+uza+mBY/VgjoGx48 lcF6lhjKxyQlrZlLLudRh5mAhGmW/p3601OGw38G8rzcxTn0AbfcXvwrfPWgoPGw60/B LbDhbBr4ii08xG/M0VnqxGCR7MHWEVSp4MsmfsNJONMA9HI3/Z9iiadft3qacRtQmLwn etXw== X-Gm-Message-State: AOAM532+XIbFjGjhfu2AwS0uoEkDzY6eSUoetdOfyIH+SLVbcmbmUuU3 sYPw0xH+ZTaQuocYsyKkfzXZKnxWUtMi X-Google-Smtp-Source: ABdhPJww2LFJLH3/iEWFznRsS4y2EKmCwtBphqqzv9jB5VDwzgIRHFNz2C3WLsjkhL62zNxYmtQfNWDgR7fd X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a63:fb0a:0:b0:3c1:cd4a:4f93 with SMTP id o10-20020a63fb0a000000b003c1cd4a4f93mr11249399pgh.78.1651534750101; Mon, 02 May 2022 16:39:10 -0700 (PDT) Date: Mon, 2 May 2022 23:38:51 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-8-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 7/9] tools: Import ARM SMCCC definitions From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Import the standard SMCCC definitions from include/linux/arm-smccc.h. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- tools/include/linux/arm-smccc.h | 193 ++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tools/include/linux/arm-smccc.h diff --git a/tools/include/linux/arm-smccc.h b/tools/include/linux/arm-smcc= c.h new file mode 100644 index 000000000000..63ce9bebccd3 --- /dev/null +++ b/tools/include/linux/arm-smccc.h @@ -0,0 +1,193 @@ +/* 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_ARCH_WORKAROUND_3 \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_32, \ + 0, 0x3fff) + +#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*/ --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E109C433FE for ; Mon, 2 May 2022 23:41:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230115AbiEBXoo (ORCPT ); Mon, 2 May 2022 19:44:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230113AbiEBXmo (ORCPT ); Mon, 2 May 2022 19:42:44 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C7BF022BCF for ; Mon, 2 May 2022 16:39:12 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-2f4dee8688cso146532577b3.16 for ; Mon, 02 May 2022 16:39:12 -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=M9rt95Qll62VSWZIYlReIizb+CqI0xc6ilrjpIZT824=; b=IDWLHlYkWMIqv+Y+rtATKkpZLOHohj5a0TNaXhf3rD2X/ZUQ4ljkm/WIPoQ6BMXSrv AzaBTzgF/bmfuQ5zdMVyo/Rzf903wbasoain6c61jwtCjlu6e2H334rMKjjrO1pKz8t0 D+Memb0caOy+DkhFw5KYaH7Fc2FrHPYMDtIwqz+bGKtrJkW/8NEc6khINKcs7QKM6Uw8 Q5d9TRM3jybjiiRZwbJAp80+gdp7G3PMSvq164HDjmuW0X75c2UaBAm/Xm9hSNOm/QEJ tT/SbwsQc1S8/HrW0JhWAlhJjpIVLt/KA4iafOeimm2gewg9ywYH9VvsHknE1rhLcnnB 8UZw== 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=M9rt95Qll62VSWZIYlReIizb+CqI0xc6ilrjpIZT824=; b=SRGwfvfNSC42VObeFnpLdKH8luwDnwoJpavf6lucyuffRpE7H56YzCaeCgymvd4az6 Xt3DU5VGMHMP6GIZACFldVDnEzCIwuFkzWaLIb+lQx1OnfHvDPvR4OzIb2Ok5EbHBXzS 9qyKAz41uPJrodL9JHFzjsZcFrPDten5qhI7etsjbGKslNPa84L6+AoJxLJUkgDQyGu5 brptiie4hSi4BzZMwCPQjPWI9ZPoS+CsnSxPqn82/BGu3ioEps2STdM9E6EBd0dc07aF HotgMJQ+lyiq4pn2NjxVDGK0kIc7oCe2+fo35JEwresDzjTqyzJl0XD2aISNq6o0mniN xKqg== X-Gm-Message-State: AOAM530P6ecqFoaMXZRmnZr/9/eux5jXygFjk0IWDfJH9Jk6TSc5MZ1l /HPO1uNQZG8h6utTqarnkvClYkxVG5GR X-Google-Smtp-Source: ABdhPJyRgAzqpgDo9K0c4tslstvhOuExAh75R2iqhFsp/aJ2b+q/+t1eauRhAxW37+EpyhfhWiJzNO2LeK8C X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a81:7b43:0:b0:2ec:8bb:3aef with SMTP id w64-20020a817b43000000b002ec08bb3aefmr13282949ywc.267.1651534751915; Mon, 02 May 2022 16:39:11 -0700 (PDT) Date: Mon, 2 May 2022 23:38:52 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-9-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 8/9] selftests: KVM: aarch64: Introduce hypercall ABI test From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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, Gavin Shan Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a KVM selftest to check the hypercall interface for arm64 platforms. The test validates the user-space' [GET|SET]_ONE_REG 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 Reviewed-by: Gavin Shan Reviewed-by: Oliver Upton --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/aarch64/hypercalls.c | 336 ++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/hypercalls.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftes= ts/kvm/.gitignore index 1bb575dfc42e..b17e464ec661 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/vcpu_width_config /aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests= /kvm/Makefile index c2cf4d318296..97eef0c03d3b 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -105,6 +105,7 @@ TEST_GEN_PROGS_x86_64 +=3D system_counter_offset_test TEST_GEN_PROGS_aarch64 +=3D aarch64/arch_timer TEST_GEN_PROGS_aarch64 +=3D aarch64/debug-exceptions TEST_GEN_PROGS_aarch64 +=3D aarch64/get-reg-list +TEST_GEN_PROGS_aarch64 +=3D aarch64/hypercalls TEST_GEN_PROGS_aarch64 +=3D aarch64/psci_test TEST_GEN_PROGS_aarch64 +=3D aarch64/vcpu_width_config TEST_GEN_PROGS_aarch64 +=3D aarch64/vgic_init diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testi= ng/selftests/kvm/aarch64/hypercalls.c new file mode 100644 index 000000000000..41e0210b7a5e --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* hypercalls: Check the ARM64's psuedo-firmware bitmap register interface. + * + * The test validates the basic hypercall functionalities that are exposed + * via the psuedo-firmware bitmap register. This includes the registers' + * read/write behavior before and after the VM has started, and if the + * hypercalls are properly masked or unmasked to the guest when disabled or + * enabled from the KVM userspace, respectively. + */ + +#include +#include +#include +#include + +#include "processor.h" + +#define FW_REG_ULIMIT_VAL(max_feat_bit) (GENMASK(max_feat_bit, 0)) + +/* Last valid bits of the bitmapped firmware registers */ +#define KVM_REG_ARM_STD_BMAP_BIT_MAX 0 +#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX 0 +#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX 1 + +struct kvm_fw_reg_info { + uint64_t reg; /* Register definition */ + uint64_t max_feat_bit; /* Bit that represents the upper limit of the feat= ure-map */ +}; + +#define FW_REG_INFO(r) \ + { \ + .reg =3D r, \ + .max_feat_bit =3D r##_BIT_MAX, \ + } + +static const struct kvm_fw_reg_info fw_reg_info[] =3D { + FW_REG_INFO(KVM_REG_ARM_STD_BMAP), + FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP), + FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP), +}; + +enum test_stage { + TEST_STAGE_REG_IFACE, + TEST_STAGE_HVC_IFACE_FEAT_DISABLED, + TEST_STAGE_HVC_IFACE_FEAT_ENABLED, + TEST_STAGE_HVC_IFACE_FALSE_INFO, + TEST_STAGE_END, +}; + +static int stage =3D TEST_STAGE_REG_IFACE; + +struct test_hvc_info { + uint32_t func_id; + uint64_t arg1; +}; + +#define TEST_HVC_INFO(f, a1) \ + { \ + .func_id =3D f, \ + .arg1 =3D a1, \ + } + +static const struct test_hvc_info hvc_info[] =3D { + /* KVM_REG_ARM_STD_BMAP */ + TEST_HVC_INFO(ARM_SMCCC_TRNG_VERSION, 0), + TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND64), + TEST_HVC_INFO(ARM_SMCCC_TRNG_GET_UUID, 0), + TEST_HVC_INFO(ARM_SMCCC_TRNG_RND32, 0), + TEST_HVC_INFO(ARM_SMCCC_TRNG_RND64, 0), + + /* KVM_REG_ARM_STD_HYP_BMAP */ + TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_HV_PV_TIME_FEATU= RES), + TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_HV_PV_TIME_ST), + TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_ST, 0), + + /* KVM_REG_ARM_VENDOR_HYP_BMAP */ + TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID, + ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID), + TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, 0), + TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, KVM_PTP_VIRT_COUNTER), +}; + +/* Feed false hypercall info to test the KVM behavior */ +static const struct test_hvc_info false_hvc_info[] =3D { + /* Feature support check against a different family of hypercalls */ + TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_= ID), + TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, ARM_SMCCC_TRNG_RND64), + TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES, ARM_SMCCC_TRNG_RND64), +}; + +static void guest_test_hvc(const struct test_hvc_info *hc_info) +{ + unsigned int i; + struct arm_smccc_res res; + unsigned int hvc_info_arr_sz; + + hvc_info_arr_sz =3D + hc_info =3D=3D hvc_info ? ARRAY_SIZE(hvc_info) : ARRAY_SIZE(false_hvc_inf= o); + + for (i =3D 0; i < hvc_info_arr_sz; i++, hc_info++) { + memset(&res, 0, sizeof(res)); + smccc_hvc(hc_info->func_id, hc_info->arg1, 0, 0, 0, 0, 0, 0, &res); + + switch (stage) { + case TEST_STAGE_HVC_IFACE_FEAT_DISABLED: + case TEST_STAGE_HVC_IFACE_FALSE_INFO: + GUEST_ASSERT_3(res.a0 =3D=3D SMCCC_RET_NOT_SUPPORTED, + res.a0, hc_info->func_id, hc_info->arg1); + break; + case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: + GUEST_ASSERT_3(res.a0 !=3D SMCCC_RET_NOT_SUPPORTED, + res.a0, hc_info->func_id, hc_info->arg1); + break; + default: + GUEST_ASSERT_1(0, stage); + } + } +} + +static void guest_code(void) +{ + while (stage !=3D 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(hvc_info); + break; + case TEST_STAGE_HVC_IFACE_FALSE_INFO: + guest_test_hvc(false_hvc_info); + 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 =3D { + .id =3D id, + .addr =3D (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 =3D { + .id =3D id, + .addr =3D (uint64_t)addr, + }; + + 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 =3D (ulong)ST_GPA_BASE; + unsigned int gpages; + struct kvm_device_attr dev =3D { + .group =3D KVM_ARM_VCPU_PVTIME_CTRL, + .attr =3D KVM_ARM_VCPU_PVTIME_IPA, + .addr =3D (uint64_t)&st_ipa, + }; + + gpages =3D 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, gpa= ges, 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 =3D 0; i < ARRAY_SIZE(fw_reg_info); i++) { + const struct kvm_fw_reg_info *reg_info =3D &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 =3D=3D FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), + "Expected all the features to be set for reg: 0x%lx; expected: 0x%lx; r= ead: 0x%lx\n", + reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit), val); + + /* Test a 'write' by disabling all the features of the register map */ + ret =3D set_fw_reg(vm, reg_info->reg, 0); + TEST_ASSERT(ret =3D=3D 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 =3D=3D 0, + "Expected all the features to be cleared for reg: 0x%lx\n", reg_info->r= eg); + + /* + * 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 =3D set_fw_reg(vm, reg_info->reg, BIT(reg_info->max_feat_bit + 1)); + TEST_ASSERT(ret !=3D 0 && errno =3D=3D 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 =3D 0; i < ARRAY_SIZE(fw_reg_info); i++) { + const struct kvm_fw_reg_info *reg_info =3D &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 =3D=3D 0, + "Expected all the features to be cleared for reg: 0x%lx\n", + reg_info->reg); + + /* + * Since the VM has run at least once, KVM shouldn't allow modification = of + * the registers and should return EBUSY. Set the registers and check for + * the expected errno. + */ + ret =3D set_fw_reg(vm, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_fe= at_bit)); + TEST_ASSERT(ret !=3D 0 && errno =3D=3D 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 =3D 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 =3D 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 =3D test_vm_create(); + break; + case TEST_STAGE_HVC_IFACE_FEAT_ENABLED: + case TEST_STAGE_HVC_IFACE_FALSE_INFO: + 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 =3D false; + + vm =3D 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 =3D test_guest_stage(vm); + break; + case UCALL_DONE: + guest_done =3D true; + break; + case UCALL_ABORT: + TEST_FAIL("%s at %s:%ld\n\tvalues: 0x%lx, 0x%lx; 0x%lx, 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; +} --=20 2.36.0.464.gb9c8b46e94-goog From nobody Sun May 10 21:55:08 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6490C433EF for ; Mon, 2 May 2022 23:42:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229936AbiEBXoT (ORCPT ); Mon, 2 May 2022 19:44:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49632 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230136AbiEBXmo (ORCPT ); Mon, 2 May 2022 19:42:44 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E4D752FFF8 for ; Mon, 2 May 2022 16:39:13 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id w3-20020a17090ac98300b001b8b914e91aso265408pjt.0 for ; Mon, 02 May 2022 16:39:13 -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=QkUuCyfxz0yjq0ch3OSwAfGOrfLGsj9nivNwXJkBK5g=; b=Tz4B+eH5HuR8q9n50g2/acZQ1++xVDSFvRimXeQDdZpwwV6NnFK5XDO0sFqEWVjyBN bc+Oht/ftGLWzoJ4M5oryTr8Xu7CvNGxEKik36VmIsd3h671BNKOGBFuexD8q0RUYnZI XKoyGdtg/FqUw6tTq7GEWV4EPY7Ci5CJ1MPNWYw+cwrGq4cnvsHswlPZJKhT9hmGGPPU ePgInDo8PXPQzXvRb5poWc4C5ubPcjNe/lQkDyN6uQ6fABWwwOUxeHQGLbp0cmb6yuSG sP/ySXKvvzS1aKN5b0npOOLzWp8ORKF6p8dUY9q5p++ixxfMUyueouQSFUzyB/KOscx/ olyw== 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=QkUuCyfxz0yjq0ch3OSwAfGOrfLGsj9nivNwXJkBK5g=; b=6ZR4EPA8ciKCdiGxHi0A9zrii0/AYG6kJQi7ucOk6og7F0OmceZ6i3RG7C+bLHoDrd ADtH4porbQtPcb/Z/mxAsLiUyDZWBaX8LSEcGCeCSCvrqHSJw8THWROvt82/SzW16Wai XriBSlp08siuQ1tgg5jYrgtJD59zfbaYF+fyqGGYTzgar9iIk6pi8NIvH46j/AsRLTmn uwuNx2uOHQDv3Ac9QYirmKBUlgG6XPBDldoPSwCnxp5OHMJOsAtTPY9cGO8d271L6OWM VbP7qzMXrEnLOCOlwnb+rcHFVt4jY5EMYY1giChkQ+PfgMRZ5zEgRLBR7E7HZ3a4ItfJ 2xGg== X-Gm-Message-State: AOAM533RUkXSK4yaE+FWhx/g8gkA1eR4d0GB8oSokhEm8m+2X7rxuVG9 A1VrHClKleeF4i5/7gksjdTlQGCtXU33 X-Google-Smtp-Source: ABdhPJzf0JCsw7wdZ8d5r0A8d1ZjwtpbuoUxsZk5ewrDKwzveAk79a48gDNabIdMRY+bMtBINrfyzwNPw8xq X-Received: from rananta-virt.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1bcc]) (user=rananta job=sendgmr) by 2002:a05:6a00:816:b0:50d:6b3d:c86f with SMTP id m22-20020a056a00081600b0050d6b3dc86fmr13482457pfk.76.1651534753259; Mon, 02 May 2022 16:39:13 -0700 (PDT) Date: Mon, 2 May 2022 23:38:53 +0000 In-Reply-To: <20220502233853.1233742-1-rananta@google.com> Message-Id: <20220502233853.1233742-10-rananta@google.com> Mime-Version: 1.0 References: <20220502233853.1233742-1-rananta@google.com> X-Mailer: git-send-email 2.36.0.464.gb9c8b46e94-goog Subject: [PATCH v7 9/9] selftests: KVM: aarch64: Add the bitmap firmware registers to get-reg-list From: Raghavendra Rao Ananta To: Marc Zyngier , Andrew Jones , James Morse , Alexandru Elisei , Suzuki K Poulose Cc: Paolo Bonzini , 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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the psuedo-firmware registers KVM_REG_ARM_STD_BMAP, KVM_REG_ARM_STD_HYP_BMAP, and KVM_REG_ARM_VENDOR_HYP_BMAP to the base_regs[] list. Also, add the COPROC support for KVM_REG_ARM_FW_FEAT_BMAP. Signed-off-by: Raghavendra Rao Ananta Reviewed-by: Oliver Upton --- tools/testing/selftests/kvm/aarch64/get-reg-list.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/testing/selftests/kvm/aarch64/get-reg-list.c b/tools/tes= ting/selftests/kvm/aarch64/get-reg-list.c index 0b571f3fe64c..d3a7dbfcbb3d 100644 --- a/tools/testing/selftests/kvm/aarch64/get-reg-list.c +++ b/tools/testing/selftests/kvm/aarch64/get-reg-list.c @@ -294,6 +294,11 @@ static void print_reg(struct vcpu_config *c, __u64 id) "%s: Unexpected bits set in FW reg id: 0x%llx", config_name(c), id); printf("\tKVM_REG_ARM_FW_REG(%lld),\n", id & 0xffff); break; + case KVM_REG_ARM_FW_FEAT_BMAP: + TEST_ASSERT(id =3D=3D KVM_REG_ARM_FW_FEAT_BMAP_REG(id & 0xffff), + "%s: Unexpected bits set in the bitmap feature FW reg id: 0x%llx", = config_name(c), id); + printf("\tKVM_REG_ARM_FW_FEAT_BMAP_REG(%lld),\n", id & 0xffff); + break; case KVM_REG_ARM64_SVE: if (has_cap(c, KVM_CAP_ARM_SVE)) printf("\t%s,\n", sve_id_to_str(c, id)); @@ -692,6 +697,9 @@ static __u64 base_regs[] =3D { KVM_REG_ARM_FW_REG(1), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1 */ KVM_REG_ARM_FW_REG(2), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2 */ KVM_REG_ARM_FW_REG(3), /* KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 */ + KVM_REG_ARM_FW_FEAT_BMAP_REG(0), /* KVM_REG_ARM_STD_BMAP */ + KVM_REG_ARM_FW_FEAT_BMAP_REG(1), /* KVM_REG_ARM_STD_HYP_BMAP */ + KVM_REG_ARM_FW_FEAT_BMAP_REG(2), /* KVM_REG_ARM_VENDOR_HYP_BMAP */ ARM64_SYS_REG(3, 3, 14, 3, 1), /* CNTV_CTL_EL0 */ ARM64_SYS_REG(3, 3, 14, 3, 2), /* CNTV_CVAL_EL0 */ ARM64_SYS_REG(3, 3, 14, 0, 2), --=20 2.36.0.464.gb9c8b46e94-goog