From: Oliver Upton <oliver.upton@linux.dev>
To: Marc Zyngier <maz@kernel.org>
Cc: James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
kvmarm@lists.linux.dev, Akihiko Odaki <akihiko.odaki@daynix.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Raghavendra Rao Ananta <rananta@google.com>,
linux-arm-kernel@lists.infradead.org,
Salil Mehta <salil.mehta@huawei.com>,
Oliver Upton <oliver.upton@linux.dev>
Subject: [RFC PATCH v2 4/6] KVM: arm64: Use a maple tree to represent the SMCCC filter
Date: Sat, 11 Feb 2023 01:37:57 +0000 [thread overview]
Message-ID: <20230211013759.3556016-5-oliver.upton@linux.dev> (raw)
In-Reply-To: <20230211013759.3556016-1-oliver.upton@linux.dev>
Maple tree is an efficient B-tree implementation that is intended for
storing non-overlapping intervals. Such a data structure is a good fit
for the SMCCC filter as it is desirable to sparsely allocate the 32 bit
function ID space.
To that end, add a maple tree to kvm_arch and correctly init/teardown
along with the VM. Wire in a test against the hypercall filter for HVCs
which does nothing until the controls are exposed to userspace.
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
---
arch/arm64/include/asm/kvm_host.h | 5 +++-
arch/arm64/kvm/arm.c | 2 ++
arch/arm64/kvm/hypercalls.c | 38 +++++++++++++++++++++++++++++++
include/kvm/arm_hypercalls.h | 1 +
4 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 012e94bc9e4a..a20875dde1f5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -16,6 +16,7 @@
#include <linux/types.h>
#include <linux/jump_label.h>
#include <linux/kvm_types.h>
+#include <linux/maple_tree.h>
#include <linux/percpu.h>
#include <linux/psci.h>
#include <asm/arch_gicv3.h>
@@ -213,7 +214,8 @@ struct kvm_arch {
#define KVM_ARCH_FLAG_EL1_32BIT 4
/* PSCI SYSTEM_SUSPEND enabled for the guest */
#define KVM_ARCH_FLAG_SYSTEM_SUSPEND_ENABLED 5
-
+ /* SMCCC filter initialized for the VM */
+#define KVM_ARCH_FLAG_SMCCC_FILTER_CONFIGURED 6
unsigned long flags;
/*
@@ -234,6 +236,7 @@ struct kvm_arch {
/* Hypercall features firmware registers' descriptor */
struct kvm_smccc_features smccc_feat;
+ struct maple_tree smccc_filter;
/*
* For an untrusted host VM, 'pkvm.handle' is used to lookup
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 09efa893e03a..e04690caad77 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -202,6 +202,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
kvm_destroy_vcpus(kvm);
kvm_unshare_hyp(kvm, kvm + 1);
+
+ kvm_arm_teardown_hypercalls(kvm);
}
int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 980546b295b3..45b8371816fd 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -121,8 +121,39 @@ static bool kvm_smccc_test_fw_bmap(struct kvm_vcpu *vcpu, u32 func_id)
}
}
+static bool kvm_smccc_filter_configured(struct kvm *kvm)
+{
+ return test_bit(KVM_ARCH_FLAG_SMCCC_FILTER_CONFIGURED, &kvm->arch.flags);
+}
+
+static u8 kvm_smccc_filter_get_action(struct kvm *kvm, u32 func_id)
+{
+ unsigned long index = func_id;
+ void *val;
+
+ if (!kvm_smccc_filter_configured(kvm))
+ return KVM_SMCCC_FILTER_ALLOW;
+
+ /*
+ * But where's the error handling, you say?
+ *
+ * mt_find() returns NULL if no entry was found, which just so happens
+ * to match KVM_SMCCC_FILTER_ALLOW.
+ */
+ val = mt_find(&kvm->arch.smccc_filter, &index, index);
+ return xa_to_value(val);
+}
+
static u8 kvm_hvc_get_action(struct kvm_vcpu *vcpu, u32 func_id)
{
+ /*
+ * Intervening actions in the SMCCC filter take precedence over the
+ * pseudo-firmware register bitmaps.
+ */
+ u8 action = kvm_smccc_filter_get_action(vcpu->kvm, func_id);
+ if (action != KVM_SMCCC_FILTER_ALLOW)
+ return action;
+
if (kvm_smccc_default_call(func_id) ||
kvm_smccc_test_fw_bmap(vcpu, func_id))
return KVM_SMCCC_FILTER_ALLOW;
@@ -256,6 +287,13 @@ void kvm_arm_init_hypercalls(struct kvm *kvm)
smccc_feat->std_bmap = KVM_ARM_SMCCC_STD_FEATURES;
smccc_feat->std_hyp_bmap = KVM_ARM_SMCCC_STD_HYP_FEATURES;
smccc_feat->vendor_hyp_bmap = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
+
+ mt_init(&kvm->arch.smccc_filter);
+}
+
+void kvm_arm_teardown_hypercalls(struct kvm *kvm)
+{
+ mtree_destroy(&kvm->arch.smccc_filter);
}
int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 1188f116cf4e..ae1ada68cdc2 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -43,6 +43,7 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
struct kvm_one_reg;
void kvm_arm_init_hypercalls(struct kvm *kvm);
+void kvm_arm_teardown_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 *uindices);
int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
--
2.39.1.581.gbfd45094c4-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-02-11 1:40 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-11 1:37 [RFC PATCH v2 0/6] KVM: arm64: Userspace SMCCC call filtering Oliver Upton
2023-02-11 1:37 ` [RFC PATCH v2 1/6] KVM: arm64: Add a helper to check if a VM has ran once Oliver Upton
2023-02-13 15:36 ` Sean Christopherson
2023-02-13 15:49 ` Marc Zyngier
2023-02-11 1:37 ` [RFC PATCH v2 2/6] KVM: arm64: Add vm fd device attribute accessors Oliver Upton
2023-02-11 1:37 ` [RFC PATCH v2 3/6] KVM: arm64: Refactor hvc filtering to support different actions Oliver Upton
2023-02-11 1:37 ` Oliver Upton [this message]
2023-02-11 1:37 ` [RFC PATCH v2 5/6] KVM: arm64: Add support for KVM_EXIT_HYPERCALL Oliver Upton
2023-02-13 16:01 ` Sean Christopherson
2023-02-13 19:24 ` Oliver Upton
2023-02-24 15:12 ` James Morse
2023-02-24 21:42 ` Oliver Upton
2023-02-11 1:37 ` [RFC PATCH v2 6/6] KVM: arm64: Indroduce support for userspace SMCCC filtering Oliver Upton
2023-02-17 18:35 ` Oliver Upton
2023-02-24 15:12 ` [RFC PATCH v2 0/6] KVM: arm64: Userspace SMCCC call filtering James Morse
2023-02-24 21:32 ` Oliver Upton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230211013759.3556016-5-oliver.upton@linux.dev \
--to=oliver.upton@linux.dev \
--cc=akihiko.odaki@daynix.com \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=rananta@google.com \
--cc=salil.mehta@huawei.com \
--cc=suzuki.poulose@arm.com \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).