[RFC PATCH v2 48/58] iommu/arm-smmu-v3-kvm: Add function to topup IOMMU allocator
Mostafa Saleh
smostafa at google.com
Thu Dec 12 10:04:12 PST 2024
The hypervisor returns requests for memory allocation in HVCs
encoded in the return registers.
Add a function that checks those returns and topup the IOMMU
alloctor in response to requests, and a macro that calls
this function around calling an HVC.
Signed-off-by: Mostafa Saleh <smostafa at google.com>
---
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
index e4a5bdc830bc..dab2d59b5a88 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-kvm.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2022 Linaro Ltd.
*/
+#include <asm/kvm_pkvm.h>
#include <asm/kvm_mmu.h>
#include <linux/of_platform.h>
@@ -28,6 +29,45 @@ static size_t kvm_arm_smmu_cur;
static size_t kvm_arm_smmu_count;
static struct hyp_arm_smmu_v3_device *kvm_arm_smmu_array;
+static int kvm_arm_smmu_topup_memcache(struct arm_smccc_res *res, gfp_t gfp)
+{
+ struct kvm_hyp_req req;
+
+ hyp_reqs_smccc_decode(res, &req);
+
+ if ((res->a1 == -ENOMEM) && (req.type != KVM_HYP_REQ_TYPE_MEM)) {
+ /*
+ * There is no way for drivers to populate hyp_alloc requests,
+ * so -ENOMEM + no request indicates that.
+ */
+ return __pkvm_topup_hyp_alloc(1);
+ } else if (req.type != KVM_HYP_REQ_TYPE_MEM) {
+ return -EBADE;
+ }
+
+ if (req.mem.dest == REQ_MEM_DEST_HYP_IOMMU) {
+ return __pkvm_topup_hyp_alloc_mgt_gfp(HYP_ALLOC_MGT_IOMMU_ID,
+ req.mem.nr_pages,
+ req.mem.sz_alloc,
+ gfp);
+ } else if (req.mem.dest == REQ_MEM_DEST_HYP_ALLOC) {
+ /* Fill hyp alloc*/
+ return __pkvm_topup_hyp_alloc(req.mem.nr_pages);
+ }
+
+ pr_err("Bogus mem request");
+ return -EBADE;
+}
+
+#define kvm_call_hyp_nvhe_mc(...) \
+({ \
+ struct arm_smccc_res __res; \
+ do { \
+ __res = kvm_call_hyp_nvhe_smccc(__VA_ARGS__); \
+ } while (__res.a1 && !kvm_arm_smmu_topup_memcache(&__res, GFP_KERNEL));\
+ __res.a1; \
+})
+
static bool kvm_arm_smmu_validate_features(struct arm_smmu_device *smmu)
{
unsigned int required_features =
--
2.47.0.338.g60cca15819-goog
More information about the linux-arm-kernel
mailing list