linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] KVM: arm64: Separate the hyp FF-A buffers init from the host
@ 2025-02-26 21:48 Sebastian Ene
  2025-02-26 21:48 ` [PATCH 1/3] KVM: arm64: Use the static initializer for the vesion lock Sebastian Ene
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Sebastian Ene @ 2025-02-26 21:48 UTC (permalink / raw)
  To: catalin.marinas, joey.gouly, maz, oliver.upton, sebastianene,
	snehalreddy, sudeep.holla, suzuki.poulose, vdonnefort, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Hello,

This moves the initialization of the hypervisor FF-A buffers
away from the host FF-A map calling path. If the hypervisor
cannot map the buffers with Trustzone, it rejects any FF-A call
when it runs under protected mode. 
Other than that it moves the definitions of the ffa_to_linux_err
map from the arm_ffa driver to the ffa header so that the hyp code
can make use of it.

Thanks,

Sebastian Ene (3):
  KVM: arm64: Use the static initializer for the vesion lock
  KVM: arm64: Map the hypervisor FF-A buffers on ffa init
  KVM: arm64: Release the ownership of the hyp rx buffer to Trustzone

 arch/arm64/kvm/hyp/nvhe/ffa.c     | 56 +++++++++++++------------------
 drivers/firmware/arm_ffa/driver.c | 24 -------------
 include/linux/arm_ffa.h           | 24 +++++++++++++
 3 files changed, 47 insertions(+), 57 deletions(-)

-- 
2.48.1.658.g4767266eb4-goog



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/3] KVM: arm64: Use the static initializer for the vesion lock
  2025-02-26 21:48 [PATCH 0/3] KVM: arm64: Separate the hyp FF-A buffers init from the host Sebastian Ene
@ 2025-02-26 21:48 ` Sebastian Ene
  2025-02-26 21:48 ` [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init Sebastian Ene
  2025-02-26 21:48 ` [PATCH 3/3] KVM: arm64: Release the ownership of the hyp rx buffer to Trustzone Sebastian Ene
  2 siblings, 0 replies; 6+ messages in thread
From: Sebastian Ene @ 2025-02-26 21:48 UTC (permalink / raw)
  To: catalin.marinas, joey.gouly, maz, oliver.upton, sebastianene,
	snehalreddy, sudeep.holla, suzuki.poulose, vdonnefort, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Replace the definition of the hypervisor version lock
with a static initializer.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/kvm/hyp/nvhe/ffa.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index e433dfab882a..6df6131f1107 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -69,7 +69,7 @@ static struct kvm_ffa_buffers hyp_buffers;
 static struct kvm_ffa_buffers host_buffers;
 static u32 hyp_ffa_version;
 static bool has_version_negotiated;
-static hyp_spinlock_t version_lock;
+static DEFINE_HYP_SPINLOCK(version_lock);
 
 static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
 {
@@ -911,6 +911,5 @@ int hyp_ffa_init(void *pages)
 		.lock	= __HYP_SPIN_LOCK_UNLOCKED,
 	};
 
-	version_lock = __HYP_SPIN_LOCK_UNLOCKED;
 	return 0;
 }
-- 
2.48.1.658.g4767266eb4-goog



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init
  2025-02-26 21:48 [PATCH 0/3] KVM: arm64: Separate the hyp FF-A buffers init from the host Sebastian Ene
  2025-02-26 21:48 ` [PATCH 1/3] KVM: arm64: Use the static initializer for the vesion lock Sebastian Ene
@ 2025-02-26 21:48 ` Sebastian Ene
  2025-02-27  9:58   ` Sudeep Holla
  2025-02-26 21:48 ` [PATCH 3/3] KVM: arm64: Release the ownership of the hyp rx buffer to Trustzone Sebastian Ene
  2 siblings, 1 reply; 6+ messages in thread
From: Sebastian Ene @ 2025-02-26 21:48 UTC (permalink / raw)
  To: catalin.marinas, joey.gouly, maz, oliver.upton, sebastianene,
	snehalreddy, sudeep.holla, suzuki.poulose, vdonnefort, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team

Map the hypervisor's buffers irrespective to the host and return
a linux error code from the FF-A error code on failure. Remove
the unmap ff-a buffers calls from the hypervisor as it will
never be called and move the definition of the
ffa_to_linux_error map in the header where it should belong to.
Prevent the host from using FF-A if the hypervisor could not
map its own buffers with Trustzone.

Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/kvm/hyp/nvhe/ffa.c     | 46 ++++++++++++-------------------
 drivers/firmware/arm_ffa/driver.c | 24 ----------------
 include/linux/arm_ffa.h           | 24 ++++++++++++++++
 3 files changed, 41 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 6df6131f1107..861f24de97cb 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -69,6 +69,7 @@ static struct kvm_ffa_buffers hyp_buffers;
 static struct kvm_ffa_buffers host_buffers;
 static u32 hyp_ffa_version;
 static bool has_version_negotiated;
+static bool has_ffa_supported;
 static DEFINE_HYP_SPINLOCK(version_lock);
 
 static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
@@ -111,30 +112,18 @@ static bool is_ffa_call(u64 func_id)
 	       ARM_SMCCC_FUNC_NUM(func_id) <= FFA_MAX_FUNC_NUM;
 }
 
-static int ffa_map_hyp_buffers(u64 ffa_page_count)
+static int ffa_map_hyp_buffers(void)
 {
 	struct arm_smccc_res res;
 
 	arm_smccc_1_1_smc(FFA_FN64_RXTX_MAP,
 			  hyp_virt_to_phys(hyp_buffers.tx),
 			  hyp_virt_to_phys(hyp_buffers.rx),
-			  ffa_page_count,
+			  KVM_FFA_MBOX_NR_PAGES,
 			  0, 0, 0, 0,
 			  &res);
 
-	return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2;
-}
-
-static int ffa_unmap_hyp_buffers(void)
-{
-	struct arm_smccc_res res;
-
-	arm_smccc_1_1_smc(FFA_RXTX_UNMAP,
-			  HOST_FFA_ID,
-			  0, 0, 0, 0, 0, 0,
-			  &res);
-
-	return res.a0 == FFA_SUCCESS ? FFA_RET_SUCCESS : res.a2;
+	return res.a0 == FFA_SUCCESS ? 0 : ffa_to_linux_errno(res.a2);
 }
 
 static void ffa_mem_frag_tx(struct arm_smccc_res *res, u32 handle_lo,
@@ -213,18 +202,10 @@ static void do_ffa_rxtx_map(struct arm_smccc_res *res,
 		goto out_unlock;
 	}
 
-	/*
-	 * Map our hypervisor buffers into the SPMD before mapping and
-	 * pinning the host buffers in our own address space.
-	 */
-	ret = ffa_map_hyp_buffers(npages);
-	if (ret)
-		goto out_unlock;
-
 	ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(tx));
 	if (ret) {
 		ret = FFA_RET_INVALID_PARAMETERS;
-		goto err_unmap;
+		goto out_unlock;
 	}
 
 	ret = __pkvm_host_share_hyp(hyp_phys_to_pfn(rx));
@@ -262,8 +243,6 @@ static void do_ffa_rxtx_map(struct arm_smccc_res *res,
 	__pkvm_host_unshare_hyp(hyp_phys_to_pfn(rx));
 err_unshare_tx:
 	__pkvm_host_unshare_hyp(hyp_phys_to_pfn(tx));
-err_unmap:
-	ffa_unmap_hyp_buffers();
 	goto out_unlock;
 }
 
@@ -291,9 +270,6 @@ static void do_ffa_rxtx_unmap(struct arm_smccc_res *res,
 	hyp_unpin_shared_mem(host_buffers.rx, host_buffers.rx + 1);
 	WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_buffers.rx)));
 	host_buffers.rx = NULL;
-
-	ffa_unmap_hyp_buffers();
-
 out_unlock:
 	hyp_spin_unlock(&host_buffers.lock);
 out:
@@ -809,6 +785,11 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
 	if (!is_ffa_call(func_id))
 		return false;
 
+	if (!has_ffa_supported) {
+		ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
+		goto out_handled;
+	}
+
 	if (!has_version_negotiated && func_id != FFA_VERSION) {
 		ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS);
 		goto out_handled;
@@ -861,6 +842,7 @@ int hyp_ffa_init(void *pages)
 {
 	struct arm_smccc_res res;
 	void *tx, *rx;
+	int ret;
 
 	if (kvm_host_psci_config.smccc_version < ARM_SMCCC_VERSION_1_2)
 		return 0;
@@ -911,5 +893,11 @@ int hyp_ffa_init(void *pages)
 		.lock	= __HYP_SPIN_LOCK_UNLOCKED,
 	};
 
+	/* Map our hypervisor buffers into the SPMD */
+	ret = ffa_map_hyp_buffers();
+	if (ret)
+		return ret;
+
+	has_ffa_supported = true;
 	return 0;
 }
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 2c2ec3c35f15..b02b80f3dfe8 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -61,30 +61,6 @@
 
 static ffa_fn *invoke_ffa_fn;
 
-static const int ffa_linux_errmap[] = {
-	/* better than switch case as long as return value is continuous */
-	0,		/* FFA_RET_SUCCESS */
-	-EOPNOTSUPP,	/* FFA_RET_NOT_SUPPORTED */
-	-EINVAL,	/* FFA_RET_INVALID_PARAMETERS */
-	-ENOMEM,	/* FFA_RET_NO_MEMORY */
-	-EBUSY,		/* FFA_RET_BUSY */
-	-EINTR,		/* FFA_RET_INTERRUPTED */
-	-EACCES,	/* FFA_RET_DENIED */
-	-EAGAIN,	/* FFA_RET_RETRY */
-	-ECANCELED,	/* FFA_RET_ABORTED */
-	-ENODATA,	/* FFA_RET_NO_DATA */
-	-EAGAIN,	/* FFA_RET_NOT_READY */
-};
-
-static inline int ffa_to_linux_errno(int errno)
-{
-	int err_idx = -errno;
-
-	if (err_idx >= 0 && err_idx < ARRAY_SIZE(ffa_linux_errmap))
-		return ffa_linux_errmap[err_idx];
-	return -EINVAL;
-}
-
 struct ffa_pcpu_irq {
 	struct ffa_drv_info *info;
 };
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 74169dd0f659..850577edadbc 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -475,4 +475,28 @@ struct ffa_ops {
 	const struct ffa_notifier_ops *notifier_ops;
 };
 
+static const int ffa_linux_errmap[] = {
+	/* better than switch case as long as return value is continuous */
+	0,		/* FFA_RET_SUCCESS */
+	-EOPNOTSUPP,	/* FFA_RET_NOT_SUPPORTED */
+	-EINVAL,	/* FFA_RET_INVALID_PARAMETERS */
+	-ENOMEM,	/* FFA_RET_NO_MEMORY */
+	-EBUSY,		/* FFA_RET_BUSY */
+	-EINTR,		/* FFA_RET_INTERRUPTED */
+	-EACCES,	/* FFA_RET_DENIED */
+	-EAGAIN,	/* FFA_RET_RETRY */
+	-ECANCELED,	/* FFA_RET_ABORTED */
+	-ENODATA,	/* FFA_RET_NO_DATA */
+	-EAGAIN,	/* FFA_RET_NOT_READY */
+};
+
+static inline int ffa_to_linux_errno(int errno)
+{
+	int err_idx = -errno;
+
+	if (err_idx >= 0 && err_idx < ARRAY_SIZE(ffa_linux_errmap))
+		return ffa_linux_errmap[err_idx];
+	return -EINVAL;
+}
+
 #endif /* _LINUX_ARM_FFA_H */
-- 
2.48.1.658.g4767266eb4-goog



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/3] KVM: arm64: Release the ownership of the hyp rx buffer to Trustzone
  2025-02-26 21:48 [PATCH 0/3] KVM: arm64: Separate the hyp FF-A buffers init from the host Sebastian Ene
  2025-02-26 21:48 ` [PATCH 1/3] KVM: arm64: Use the static initializer for the vesion lock Sebastian Ene
  2025-02-26 21:48 ` [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init Sebastian Ene
@ 2025-02-26 21:48 ` Sebastian Ene
  2 siblings, 0 replies; 6+ messages in thread
From: Sebastian Ene @ 2025-02-26 21:48 UTC (permalink / raw)
  To: catalin.marinas, joey.gouly, maz, oliver.upton, sebastianene,
	snehalreddy, sudeep.holla, suzuki.poulose, vdonnefort, will,
	yuzenghui
  Cc: kvmarm, linux-arm-kernel, linux-kernel, kernel-team,
	Andrei Homescu

Introduce the release FF-A call to notify Trustzone that the hypervisor
has finished copying the data from the buffer shared with Trustzone to
the non-secure partition.

Reported-by: Andrei Homescu <ahomescu@google.com>
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
 arch/arm64/kvm/hyp/nvhe/ffa.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 861f24de97cb..7da0203f1ee9 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -725,6 +725,7 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
 	DECLARE_REG(u32, uuid3, ctxt, 4);
 	DECLARE_REG(u32, flags, ctxt, 5);
 	u32 count, partition_sz, copy_sz;
+	struct arm_smccc_res _res;
 
 	hyp_spin_lock(&host_buffers.lock);
 	if (!host_buffers.rx) {
@@ -741,7 +742,7 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
 
 	count = res->a2;
 	if (!count)
-		goto out_unlock;
+		goto release_rx;
 
 	if (hyp_ffa_version > FFA_VERSION_1_0) {
 		/* Get the number of partitions deployed in the system */
@@ -757,10 +758,12 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
 	copy_sz = partition_sz * count;
 	if (copy_sz > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
 		ffa_to_smccc_res(res, FFA_RET_ABORTED);
-		goto out_unlock;
+		goto release_rx;
 	}
 
 	memcpy(host_buffers.rx, hyp_buffers.rx, copy_sz);
+release_rx:
+	ffa_rx_release(&_res);
 out_unlock:
 	hyp_spin_unlock(&host_buffers.lock);
 }
-- 
2.48.1.658.g4767266eb4-goog



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init
  2025-02-26 21:48 ` [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init Sebastian Ene
@ 2025-02-27  9:58   ` Sudeep Holla
  2025-02-27 17:58     ` Sebastian Ene
  0 siblings, 1 reply; 6+ messages in thread
From: Sudeep Holla @ 2025-02-27  9:58 UTC (permalink / raw)
  To: Sebastian Ene
  Cc: catalin.marinas, joey.gouly, maz, Sudeep Holla, oliver.upton,
	snehalreddy, suzuki.poulose, vdonnefort, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Wed, Feb 26, 2025 at 09:48:52PM +0000, Sebastian Ene wrote:
> Map the hypervisor's buffers irrespective to the host and return
> a linux error code from the FF-A error code on failure. Remove
> the unmap ff-a buffers calls from the hypervisor as it will
> never be called and move the definition of the
> ffa_to_linux_error map in the header where it should belong to.
> Prevent the host from using FF-A if the hypervisor could not
> map its own buffers with Trustzone.
> 
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
> ---
>  arch/arm64/kvm/hyp/nvhe/ffa.c     | 46 ++++++++++++-------------------
>  drivers/firmware/arm_ffa/driver.c | 24 ----------------
>  include/linux/arm_ffa.h           | 24 ++++++++++++++++

Can you post the code movement from driver to the header as separate patch
so that I can take it separately to avoid conflicts with the other changes
I have. It could be just fine but I see no reason as why it can't be a
separate change or why it needs to be bundled here.

-- 
Regards,
Sudeep


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init
  2025-02-27  9:58   ` Sudeep Holla
@ 2025-02-27 17:58     ` Sebastian Ene
  0 siblings, 0 replies; 6+ messages in thread
From: Sebastian Ene @ 2025-02-27 17:58 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: catalin.marinas, joey.gouly, maz, oliver.upton, snehalreddy,
	suzuki.poulose, vdonnefort, will, yuzenghui, kvmarm,
	linux-arm-kernel, linux-kernel, kernel-team

On Thu, Feb 27, 2025 at 09:58:28AM +0000, Sudeep Holla wrote:
> On Wed, Feb 26, 2025 at 09:48:52PM +0000, Sebastian Ene wrote:
> > Map the hypervisor's buffers irrespective to the host and return
> > a linux error code from the FF-A error code on failure. Remove
> > the unmap ff-a buffers calls from the hypervisor as it will
> > never be called and move the definition of the
> > ffa_to_linux_error map in the header where it should belong to.
> > Prevent the host from using FF-A if the hypervisor could not
> > map its own buffers with Trustzone.
> > 
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > ---
> >  arch/arm64/kvm/hyp/nvhe/ffa.c     | 46 ++++++++++++-------------------
> >  drivers/firmware/arm_ffa/driver.c | 24 ----------------
> >  include/linux/arm_ffa.h           | 24 ++++++++++++++++

Hi Sudeep,

> 
> Can you post the code movement from driver to the header as separate patch
> so that I can take it separately to avoid conflicts with the other changes
> I have. It could be just fine but I see no reason as why it can't be a
> separate change or why it needs to be bundled here.

Yes, let me do that and I will spin up a v2.

Thanks,
Sebastian

> 
> -- 
> Regards,
> Sudeep


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-02-27 19:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-26 21:48 [PATCH 0/3] KVM: arm64: Separate the hyp FF-A buffers init from the host Sebastian Ene
2025-02-26 21:48 ` [PATCH 1/3] KVM: arm64: Use the static initializer for the vesion lock Sebastian Ene
2025-02-26 21:48 ` [PATCH 2/3] KVM: arm64: Map the hypervisor FF-A buffers on ffa init Sebastian Ene
2025-02-27  9:58   ` Sudeep Holla
2025-02-27 17:58     ` Sebastian Ene
2025-02-26 21:48 ` [PATCH 3/3] KVM: arm64: Release the ownership of the hyp rx buffer to Trustzone Sebastian Ene

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).