* [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-01 20:45 [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Seth Forshee
@ 2026-06-01 20:45 ` Seth Forshee
2026-06-02 15:56 ` Sudeep Holla
2026-06-01 20:45 ` [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails Seth Forshee
2026-06-02 16:51 ` [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Sudeep Holla
2 siblings, 1 reply; 14+ messages in thread
From: Seth Forshee @ 2026-06-01 20:45 UTC (permalink / raw)
To: Sudeep Holla, Sebastian Ene; +Cc: linux-arm-kernel, linux-kernel, Seth Forshee
FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
size is not checked when page-aligning the RX/TX buffer size, and
FFA_RXTX_MAP may fail when passed a size greater than the maximum.
Decode the maximum buffer size returned from FFA_FEATURES and limit the
buffer size based on this value if it is non-zero (zero indicates no
maximum). Include verification that the max returned by the SPMC is
larger than the minimum, otherwise use the minimum.
While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
consistency.
Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Seth Forshee <sforshee@nvidia.com>
---
drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index b9f17fda7243..dc45724a29ba 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/mutex.h>
@@ -55,7 +56,9 @@
(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
#define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
-#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
+#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
+#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
+#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
#define FFA_MAX_NOTIFICATIONS 64
@@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
ffa_notifications_cleanup();
}
+#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
+
static int __init ffa_init(void)
{
int ret;
u32 buf_sz;
- size_t rxtx_bufsz = SZ_4K;
+ size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
ret = ffa_transport_init(&invoke_ffa_fn);
if (ret)
@@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
rxtx_bufsz = SZ_16K;
else
rxtx_bufsz = SZ_4K;
+
+ if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
+ rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
+ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_bufsz) {
+ /*
+ * Per spec the maximum must be >= the minimum, or
+ * else zero if there is no size limit. If the SPMC
+ * violates this constraint, use the minimum as the
+ * effective maximum.
+ */
+ rxtx_max_bufsz = rxtx_bufsz;
+ }
+ }
}
+ /*
+ * alloc_pages_exact() allocates full pages. Use the full allocated
+ * space up to the max supported by the SPMC.
+ */
rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
+ if (rxtx_max_bufsz)
+ rxtx_bufsz = min(rxtx_bufsz, rxtx_max_bufsz);
+
drv_info->rxtx_bufsz = rxtx_bufsz;
drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
if (!drv_info->rx_buffer) {
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-01 20:45 ` [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size Seth Forshee
@ 2026-06-02 15:56 ` Sudeep Holla
2026-06-02 16:12 ` Seth Forshee
0 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2026-06-02 15:56 UTC (permalink / raw)
To: Seth Forshee; +Cc: Sebastian Ene, Sudeep Holla, linux-arm-kernel, linux-kernel
On Mon, Jun 01, 2026 at 03:45:11PM -0500, Seth Forshee wrote:
> FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
> size is not checked when page-aligning the RX/TX buffer size, and
> FFA_RXTX_MAP may fail when passed a size greater than the maximum.
>
> Decode the maximum buffer size returned from FFA_FEATURES and limit the
> buffer size based on this value if it is non-zero (zero indicates no
> maximum). Include verification that the max returned by the SPMC is
> larger than the minimum, otherwise use the minimum.
>
> While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
> consistency.
>
> Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> ---
> drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
> 1 file changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index b9f17fda7243..dc45724a29ba 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -32,6 +32,7 @@
> #include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> +#include <linux/minmax.h>
> #include <linux/module.h>
> #include <linux/mm.h>
> #include <linux/mutex.h>
> @@ -55,7 +56,9 @@
> (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
>
> #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
>
> #define FFA_MAX_NOTIFICATIONS 64
>
> @@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
> ffa_notifications_cleanup();
> }
>
> +#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
> +
> static int __init ffa_init(void)
> {
> int ret;
> u32 buf_sz;
> - size_t rxtx_bufsz = SZ_4K;
> + size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
>
> ret = ffa_transport_init(&invoke_ffa_fn);
> if (ret)
> @@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
> rxtx_bufsz = SZ_16K;
> else
> rxtx_bufsz = SZ_4K;
> +
> + if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
This is not even compile tested ? I don't think this is defined anyway.
Anyways I don't think we need this condition as v1.1 or below had it
MBZ, so it is fine to drop it.
> + rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
The cast is unnecessary, its is 16 bit, so max 0xFFFF << 12.
> + if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_bufsz) {
> + /*
> + * Per spec the maximum must be >= the minimum, or
> + * else zero if there is no size limit. If the SPMC
> + * violates this constraint, use the minimum as the
> + * effective maximum.
> + */
I don't see any text implying the above from the spec, drop it. Please point
it to me if you find. Even otherwise it seems obvious here and doesn't need
the note.
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-02 15:56 ` Sudeep Holla
@ 2026-06-02 16:12 ` Seth Forshee
2026-06-02 16:27 ` Sudeep Holla
0 siblings, 1 reply; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 16:12 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 04:56:48PM +0100, Sudeep Holla wrote:
> On Mon, Jun 01, 2026 at 03:45:11PM -0500, Seth Forshee wrote:
> > FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
> > size is not checked when page-aligning the RX/TX buffer size, and
> > FFA_RXTX_MAP may fail when passed a size greater than the maximum.
> >
> > Decode the maximum buffer size returned from FFA_FEATURES and limit the
> > buffer size based on this value if it is non-zero (zero indicates no
> > maximum). Include verification that the max returned by the SPMC is
> > larger than the minimum, otherwise use the minimum.
> >
> > While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
> > consistency.
> >
> > Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
> > Assisted-by: Claude:claude-opus-4-8
> > Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> > ---
> > drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
> > 1 file changed, 27 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> > index b9f17fda7243..dc45724a29ba 100644
> > --- a/drivers/firmware/arm_ffa/driver.c
> > +++ b/drivers/firmware/arm_ffa/driver.c
> > @@ -32,6 +32,7 @@
> > #include <linux/interrupt.h>
> > #include <linux/io.h>
> > #include <linux/kernel.h>
> > +#include <linux/minmax.h>
> > #include <linux/module.h>
> > #include <linux/mm.h>
> > #include <linux/mutex.h>
> > @@ -55,7 +56,9 @@
> > (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
> >
> > #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> > -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> > +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> > +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> > +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
> >
> > #define FFA_MAX_NOTIFICATIONS 64
> >
> > @@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
> > ffa_notifications_cleanup();
> > }
> >
> > +#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
> > +
> > static int __init ffa_init(void)
> > {
> > int ret;
> > u32 buf_sz;
> > - size_t rxtx_bufsz = SZ_4K;
> > + size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
> >
> > ret = ffa_transport_init(&invoke_ffa_fn);
> > if (ret)
> > @@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
> > rxtx_bufsz = SZ_16K;
> > else
> > rxtx_bufsz = SZ_4K;
> > +
> > + if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
>
> This is not even compile tested ? I don't think this is defined anyway.
> Anyways I don't think we need this condition as v1.1 or below had it
> MBZ, so it is fine to drop it.
It is added just above ffa_init(). The code as been compile and run
tested on multiple platforms, as noted in the cover letter.
I hadn't checked older spec versions, so if they have it as MBZ then I
agree we can drop the check.
>
> > + rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
>
> The cast is unnecessary, its is 16 bit, so max 0xFFFF << 12.
Correct, though linters complain about it which is why I added it. I can
drop it though if you prefer.
>
>
> > + if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_bufsz) {
> > + /*
> > + * Per spec the maximum must be >= the minimum, or
> > + * else zero if there is no size limit. If the SPMC
> > + * violates this constraint, use the minimum as the
> > + * effective maximum.
> > + */
>
> I don't see any text implying the above from the spec, drop it. Please point
> it to me if you find. Even otherwise it seems obvious here and doesn't need
> the note.
I found it in v1.3 of the spec in Table 13.15: "Size must be greater or
equal to the minimum buffer size, else MBZ if there is no size limit." I
will remove the comment.
Thanks,
Seth
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-02 16:12 ` Seth Forshee
@ 2026-06-02 16:27 ` Sudeep Holla
2026-06-02 17:05 ` Seth Forshee
0 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2026-06-02 16:27 UTC (permalink / raw)
To: Seth Forshee; +Cc: Sebastian Ene, Sudeep Holla, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 11:12:03AM -0500, Seth Forshee wrote:
> On Tue, Jun 02, 2026 at 04:56:48PM +0100, Sudeep Holla wrote:
> > On Mon, Jun 01, 2026 at 03:45:11PM -0500, Seth Forshee wrote:
> > > FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
> > > size is not checked when page-aligning the RX/TX buffer size, and
> > > FFA_RXTX_MAP may fail when passed a size greater than the maximum.
> > >
> > > Decode the maximum buffer size returned from FFA_FEATURES and limit the
> > > buffer size based on this value if it is non-zero (zero indicates no
> > > maximum). Include verification that the max returned by the SPMC is
> > > larger than the minimum, otherwise use the minimum.
> > >
> > > While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
> > > consistency.
> > >
> > > Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
> > > Assisted-by: Claude:claude-opus-4-8
> > > Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> > > ---
> > > drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
> > > 1 file changed, 27 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> > > index b9f17fda7243..dc45724a29ba 100644
> > > --- a/drivers/firmware/arm_ffa/driver.c
> > > +++ b/drivers/firmware/arm_ffa/driver.c
> > > @@ -32,6 +32,7 @@
> > > #include <linux/interrupt.h>
> > > #include <linux/io.h>
> > > #include <linux/kernel.h>
> > > +#include <linux/minmax.h>
> > > #include <linux/module.h>
> > > #include <linux/mm.h>
> > > #include <linux/mutex.h>
> > > @@ -55,7 +56,9 @@
> > > (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
> > >
> > > #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> > > -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> > > +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> > > +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> > > +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
> > >
> > > #define FFA_MAX_NOTIFICATIONS 64
> > >
> > > @@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
> > > ffa_notifications_cleanup();
> > > }
> > >
> > > +#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
> > > +
> > > static int __init ffa_init(void)
> > > {
> > > int ret;
> > > u32 buf_sz;
> > > - size_t rxtx_bufsz = SZ_4K;
> > > + size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
> > >
> > > ret = ffa_transport_init(&invoke_ffa_fn);
> > > if (ret)
> > > @@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
> > > rxtx_bufsz = SZ_16K;
> > > else
> > > rxtx_bufsz = SZ_4K;
> > > +
> > > + if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
> >
> > This is not even compile tested ? I don't think this is defined anyway.
> > Anyways I don't think we need this condition as v1.1 or below had it
> > MBZ, so it is fine to drop it.
>
> It is added just above ffa_init(). The code as been compile and run
> tested on multiple platforms, as noted in the cover letter.
>
Ah sorry, my bad. It failed to apply and I must have messed it up.
I have some changes in linux-next which conflicts and I dropped it when
resolving. Sorry for that.
> I hadn't checked older spec versions, so if they have it as MBZ then I
> agree we can drop the check.
>
> >
> > > + rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
> >
> > The cast is unnecessary, its is 16 bit, so max 0xFFFF << 12.
>
> Correct, though linters complain about it which is why I added it. I can
> drop it though if you prefer.
>
Can you be more specific ? Any way to trigger it ?
> >
> >
> > > + if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_bufsz) {
> > > + /*
> > > + * Per spec the maximum must be >= the minimum, or
> > > + * else zero if there is no size limit. If the SPMC
> > > + * violates this constraint, use the minimum as the
> > > + * effective maximum.
> > > + */
> >
> > I don't see any text implying the above from the spec, drop it. Please point
> > it to me if you find. Even otherwise it seems obvious here and doesn't need
> > the note.
>
> I found it in v1.3 of the spec in Table 13.15: "Size must be greater or
> equal to the minimum buffer size, else MBZ if there is no size limit." I
> will remove the comment.
>
Ah v1.3, sorry I was just looking at v1.2.
> Thanks,
> Seth
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-02 16:27 ` Sudeep Holla
@ 2026-06-02 17:05 ` Seth Forshee
2026-06-02 21:58 ` Seth Forshee
0 siblings, 1 reply; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 17:05 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 05:27:48PM +0100, Sudeep Holla wrote:
> On Tue, Jun 02, 2026 at 11:12:03AM -0500, Seth Forshee wrote:
> > On Tue, Jun 02, 2026 at 04:56:48PM +0100, Sudeep Holla wrote:
> > > On Mon, Jun 01, 2026 at 03:45:11PM -0500, Seth Forshee wrote:
> > > > FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
> > > > size is not checked when page-aligning the RX/TX buffer size, and
> > > > FFA_RXTX_MAP may fail when passed a size greater than the maximum.
> > > >
> > > > Decode the maximum buffer size returned from FFA_FEATURES and limit the
> > > > buffer size based on this value if it is non-zero (zero indicates no
> > > > maximum). Include verification that the max returned by the SPMC is
> > > > larger than the minimum, otherwise use the minimum.
> > > >
> > > > While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
> > > > consistency.
> > > >
> > > > Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
> > > > Assisted-by: Claude:claude-opus-4-8
> > > > Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> > > > ---
> > > > drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
> > > > 1 file changed, 27 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> > > > index b9f17fda7243..dc45724a29ba 100644
> > > > --- a/drivers/firmware/arm_ffa/driver.c
> > > > +++ b/drivers/firmware/arm_ffa/driver.c
> > > > @@ -32,6 +32,7 @@
> > > > #include <linux/interrupt.h>
> > > > #include <linux/io.h>
> > > > #include <linux/kernel.h>
> > > > +#include <linux/minmax.h>
> > > > #include <linux/module.h>
> > > > #include <linux/mm.h>
> > > > #include <linux/mutex.h>
> > > > @@ -55,7 +56,9 @@
> > > > (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
> > > >
> > > > #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> > > > -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> > > > +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> > > > +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> > > > +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
> > > >
> > > > #define FFA_MAX_NOTIFICATIONS 64
> > > >
> > > > @@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
> > > > ffa_notifications_cleanup();
> > > > }
> > > >
> > > > +#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
> > > > +
> > > > static int __init ffa_init(void)
> > > > {
> > > > int ret;
> > > > u32 buf_sz;
> > > > - size_t rxtx_bufsz = SZ_4K;
> > > > + size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
> > > >
> > > > ret = ffa_transport_init(&invoke_ffa_fn);
> > > > if (ret)
> > > > @@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
> > > > rxtx_bufsz = SZ_16K;
> > > > else
> > > > rxtx_bufsz = SZ_4K;
> > > > +
> > > > + if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
> > >
> > > This is not even compile tested ? I don't think this is defined anyway.
> > > Anyways I don't think we need this condition as v1.1 or below had it
> > > MBZ, so it is fine to drop it.
> >
> > It is added just above ffa_init(). The code as been compile and run
> > tested on multiple platforms, as noted in the cover letter.
> >
>
> Ah sorry, my bad. It failed to apply and I must have messed it up.
> I have some changes in linux-next which conflicts and I dropped it when
> resolving. Sorry for that.
>
> > I hadn't checked older spec versions, so if they have it as MBZ then I
> > agree we can drop the check.
> >
> > >
> > > > + rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
> > >
> > > The cast is unnecessary, its is 16 bit, so max 0xFFFF << 12.
> >
> > Correct, though linters complain about it which is why I added it. I can
> > drop it though if you prefer.
> >
>
> Can you be more specific ? Any way to trigger it ?
I've been trying out various tools for reviwing/analyzing patches, so I
don't remember now which one(s) complained about this. But I'll run the
patches back through them after I make the updates you've requested and
let you know.
Seth
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size
2026-06-02 17:05 ` Seth Forshee
@ 2026-06-02 21:58 ` Seth Forshee
0 siblings, 0 replies; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 21:58 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 12:05:47PM -0500, Seth Forshee wrote:
> On Tue, Jun 02, 2026 at 05:27:48PM +0100, Sudeep Holla wrote:
> > On Tue, Jun 02, 2026 at 11:12:03AM -0500, Seth Forshee wrote:
> > > On Tue, Jun 02, 2026 at 04:56:48PM +0100, Sudeep Holla wrote:
> > > > On Mon, Jun 01, 2026 at 03:45:11PM -0500, Seth Forshee wrote:
> > > > > FFA_FEATURES in v1.2+ supports a maximum RXTX_MAP size. This maximum
> > > > > size is not checked when page-aligning the RX/TX buffer size, and
> > > > > FFA_RXTX_MAP may fail when passed a size greater than the maximum.
> > > > >
> > > > > Decode the maximum buffer size returned from FFA_FEATURES and limit the
> > > > > buffer size based on this value if it is non-zero (zero indicates no
> > > > > maximum). Include verification that the max returned by the SPMC is
> > > > > larger than the minimum, otherwise use the minimum.
> > > > >
> > > > > While there, also update RXTX_MAP_MIN_BUFSZ() to use FIELD_GET() for
> > > > > consistency.
> > > > >
> > > > > Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
> > > > > Assisted-by: Claude:claude-opus-4-8
> > > > > Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> > > > > ---
> > > > > drivers/firmware/arm_ffa/driver.c | 29 +++++++++++++++++++++++++++--
> > > > > 1 file changed, 27 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> > > > > index b9f17fda7243..dc45724a29ba 100644
> > > > > --- a/drivers/firmware/arm_ffa/driver.c
> > > > > +++ b/drivers/firmware/arm_ffa/driver.c
> > > > > @@ -32,6 +32,7 @@
> > > > > #include <linux/interrupt.h>
> > > > > #include <linux/io.h>
> > > > > #include <linux/kernel.h>
> > > > > +#include <linux/minmax.h>
> > > > > #include <linux/module.h>
> > > > > #include <linux/mm.h>
> > > > > #include <linux/mutex.h>
> > > > > @@ -55,7 +56,9 @@
> > > > > (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
> > > > >
> > > > > #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> > > > > -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> > > > > +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> > > > > +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> > > > > +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
> > > > >
> > > > > #define FFA_MAX_NOTIFICATIONS 64
> > > > >
> > > > > @@ -2086,11 +2089,13 @@ static void ffa_notifications_setup(void)
> > > > > ffa_notifications_cleanup();
> > > > > }
> > > > >
> > > > > +#define FFA_SUPPORTS_RXTX_MAX_BUFSZ(version) ((version) > FFA_VERSION_1_1)
> > > > > +
> > > > > static int __init ffa_init(void)
> > > > > {
> > > > > int ret;
> > > > > u32 buf_sz;
> > > > > - size_t rxtx_bufsz = SZ_4K;
> > > > > + size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
> > > > >
> > > > > ret = ffa_transport_init(&invoke_ffa_fn);
> > > > > if (ret)
> > > > > @@ -2118,9 +2123,29 @@ static int __init ffa_init(void)
> > > > > rxtx_bufsz = SZ_16K;
> > > > > else
> > > > > rxtx_bufsz = SZ_4K;
> > > > > +
> > > > > + if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
> > > >
> > > > This is not even compile tested ? I don't think this is defined anyway.
> > > > Anyways I don't think we need this condition as v1.1 or below had it
> > > > MBZ, so it is fine to drop it.
> > >
> > > It is added just above ffa_init(). The code as been compile and run
> > > tested on multiple platforms, as noted in the cover letter.
> > >
> >
> > Ah sorry, my bad. It failed to apply and I must have messed it up.
> > I have some changes in linux-next which conflicts and I dropped it when
> > resolving. Sorry for that.
> >
> > > I hadn't checked older spec versions, so if they have it as MBZ then I
> > > agree we can drop the check.
> > >
> > > >
> > > > > + rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
> > > >
> > > > The cast is unnecessary, its is 16 bit, so max 0xFFFF << 12.
> > >
> > > Correct, though linters complain about it which is why I added it. I can
> > > drop it though if you prefer.
> > >
> >
> > Can you be more specific ? Any way to trigger it ?
>
> I've been trying out various tools for reviwing/analyzing patches, so I
> don't remember now which one(s) complained about this. But I'll run the
> patches back through them after I make the updates you've requested and
> let you know.
Nothing flagged it this time, but I'm sure I only added it originally
after a tool flagged it. However it got there, it's removed in v2.
Seth
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
2026-06-01 20:45 [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Seth Forshee
2026-06-01 20:45 ` [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size Seth Forshee
@ 2026-06-01 20:45 ` Seth Forshee
2026-06-02 15:48 ` Sudeep Holla
2026-06-02 16:51 ` [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Sudeep Holla
2 siblings, 1 reply; 14+ messages in thread
From: Seth Forshee @ 2026-06-01 20:45 UTC (permalink / raw)
To: Sudeep Holla, Sebastian Ene; +Cc: linux-arm-kernel, linux-kernel, Seth Forshee
FFA_FEATURES only supports a maximum size value for RXTX_MAP in v1.2+.
Older implementations may still reject larger sizes, which can happen
when the minimum size is rounded up to the page size when PAGE_SIZE >
4K.
Fall back to the minimum size when RXTX_MAP fails with
INVALID_PARAMETERS to fix the regression on these platforms. This also
has the side effect of falling back for v1.2+ with a maximum of 0 (i.e.
no maximum), where the rounded-up value isn't expected to be rejected,
but there's no harm in retrying with a smaller size and it might even be
of benefit for a non-compliant SPMC.
Note that this may result in passing a size smaller than the allocated
size to free_pages_exact(). This does not result in any leaked memory,
since the size extends into all allocated pages, and free_pages_exact()
correctly handles sizes which are not page aligned.
Fixes: 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size during RXTX_MAP")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Seth Forshee <sforshee@nvidia.com>
---
drivers/firmware/arm_ffa/driver.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index dc45724a29ba..60ad58e229ce 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -2095,7 +2095,7 @@ static int __init ffa_init(void)
{
int ret;
u32 buf_sz;
- size_t rxtx_bufsz = SZ_4K, rxtx_max_bufsz = 0;
+ size_t rxtx_min_bufsz = SZ_4K, rxtx_max_bufsz = 0, rxtx_bufsz;
ret = ffa_transport_init(&invoke_ffa_fn);
if (ret)
@@ -2118,22 +2118,22 @@ static int __init ffa_init(void)
ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
if (!ret) {
if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
- rxtx_bufsz = SZ_64K;
+ rxtx_min_bufsz = SZ_64K;
else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
- rxtx_bufsz = SZ_16K;
+ rxtx_min_bufsz = SZ_16K;
else
- rxtx_bufsz = SZ_4K;
+ rxtx_min_bufsz = SZ_4K;
if (FFA_SUPPORTS_RXTX_MAX_BUFSZ(drv_info->version)) {
rxtx_max_bufsz = (size_t)RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
- if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_bufsz) {
+ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz) {
/*
* Per spec the maximum must be >= the minimum, or
* else zero if there is no size limit. If the SPMC
* violates this constraint, use the minimum as the
* effective maximum.
*/
- rxtx_max_bufsz = rxtx_bufsz;
+ rxtx_max_bufsz = rxtx_min_bufsz;
}
}
}
@@ -2142,7 +2142,7 @@ static int __init ffa_init(void)
* alloc_pages_exact() allocates full pages. Use the full allocated
* space up to the max supported by the SPMC.
*/
- rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
+ rxtx_bufsz = PAGE_ALIGN(rxtx_min_bufsz);
if (rxtx_max_bufsz)
rxtx_bufsz = min(rxtx_bufsz, rxtx_max_bufsz);
@@ -2162,6 +2162,20 @@ static int __init ffa_init(void)
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
virt_to_phys(drv_info->rx_buffer),
rxtx_bufsz / FFA_PAGE_SIZE);
+ if (ret == -EINVAL && rxtx_max_bufsz == 0 && rxtx_min_bufsz < rxtx_bufsz) {
+ /*
+ * FFA_FEATURES only supports maximum buffer size in v1.2+,
+ * and some implementations without it may fail when the
+ * buffer size is rounded up to a larger page size. If
+ * RXTX_MAP fails due to invalid parameters, try again with
+ * the minimum buffer size.
+ */
+ rxtx_bufsz = rxtx_min_bufsz;
+ drv_info->rxtx_bufsz = rxtx_bufsz;
+ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+ virt_to_phys(drv_info->rx_buffer),
+ rxtx_bufsz / FFA_PAGE_SIZE);
+ }
if (ret) {
pr_err("failed to register FFA RxTx buffers\n");
goto free_pages;
--
2.43.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
2026-06-01 20:45 ` [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails Seth Forshee
@ 2026-06-02 15:48 ` Sudeep Holla
2026-06-02 16:21 ` Seth Forshee
0 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2026-06-02 15:48 UTC (permalink / raw)
To: Seth Forshee; +Cc: Sebastian Ene, Sudeep Holla, linux-arm-kernel, linux-kernel
On Mon, Jun 01, 2026 at 03:45:12PM -0500, Seth Forshee wrote:
> FFA_FEATURES only supports a maximum size value for RXTX_MAP in v1.2+.
> Older implementations may still reject larger sizes, which can happen
> when the minimum size is rounded up to the page size when PAGE_SIZE >
> 4K.
>
> Fall back to the minimum size when RXTX_MAP fails with
> INVALID_PARAMETERS to fix the regression on these platforms. This also
> has the side effect of falling back for v1.2+ with a maximum of 0 (i.e.
> no maximum), where the rounded-up value isn't expected to be rejected,
> but there's no harm in retrying with a smaller size and it might even be
> of benefit for a non-compliant SPMC.
>
Is this needed on any of your platforms ? I don't want to push a solution
or fallback/workaround if there are no users for it.
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
2026-06-02 15:48 ` Sudeep Holla
@ 2026-06-02 16:21 ` Seth Forshee
2026-06-02 16:29 ` Sudeep Holla
0 siblings, 1 reply; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 16:21 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 04:48:11PM +0100, Sudeep Holla wrote:
> On Mon, Jun 01, 2026 at 03:45:12PM -0500, Seth Forshee wrote:
> > FFA_FEATURES only supports a maximum size value for RXTX_MAP in v1.2+.
> > Older implementations may still reject larger sizes, which can happen
> > when the minimum size is rounded up to the page size when PAGE_SIZE >
> > 4K.
> >
> > Fall back to the minimum size when RXTX_MAP fails with
> > INVALID_PARAMETERS to fix the regression on these platforms. This also
> > has the side effect of falling back for v1.2+ with a maximum of 0 (i.e.
> > no maximum), where the rounded-up value isn't expected to be rejected,
> > but there's no harm in retrying with a smaller size and it might even be
> > of benefit for a non-compliant SPMC.
> >
>
> Is this needed on any of your platforms ? I don't want to push a solution
> or fallback/workaround if there are no users for it.
Yes, we have platforms for which commit 83210251fd70 causes RXTX_MAP
failures with page sizes larger than 4K.
Thanks,
Seth
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
2026-06-02 16:21 ` Seth Forshee
@ 2026-06-02 16:29 ` Sudeep Holla
2026-06-02 17:12 ` Seth Forshee
0 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2026-06-02 16:29 UTC (permalink / raw)
To: Seth Forshee; +Cc: Sebastian Ene, Sudeep Holla, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 11:21:33AM -0500, Seth Forshee wrote:
> On Tue, Jun 02, 2026 at 04:48:11PM +0100, Sudeep Holla wrote:
> > On Mon, Jun 01, 2026 at 03:45:12PM -0500, Seth Forshee wrote:
> > > FFA_FEATURES only supports a maximum size value for RXTX_MAP in v1.2+.
> > > Older implementations may still reject larger sizes, which can happen
> > > when the minimum size is rounded up to the page size when PAGE_SIZE >
> > > 4K.
> > >
> > > Fall back to the minimum size when RXTX_MAP fails with
> > > INVALID_PARAMETERS to fix the regression on these platforms. This also
> > > has the side effect of falling back for v1.2+ with a maximum of 0 (i.e.
> > > no maximum), where the rounded-up value isn't expected to be rejected,
> > > but there's no harm in retrying with a smaller size and it might even be
> > > of benefit for a non-compliant SPMC.
> > >
> >
> > Is this needed on any of your platforms ? I don't want to push a solution
> > or fallback/workaround if there are no users for it.
>
> Yes, we have platforms for which commit 83210251fd70 causes RXTX_MAP
> failures with page sizes larger than 4K.
>
And they are FF-A v1.1 or doesn't set max_buf size ? Sorry for being
pedantic, just want to be sure it is useful on real platforms before
pushing it as fix/workaround.
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
2026-06-02 16:29 ` Sudeep Holla
@ 2026-06-02 17:12 ` Seth Forshee
0 siblings, 0 replies; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 17:12 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 05:29:37PM +0100, Sudeep Holla wrote:
> On Tue, Jun 02, 2026 at 11:21:33AM -0500, Seth Forshee wrote:
> > On Tue, Jun 02, 2026 at 04:48:11PM +0100, Sudeep Holla wrote:
> > > On Mon, Jun 01, 2026 at 03:45:12PM -0500, Seth Forshee wrote:
> > > > FFA_FEATURES only supports a maximum size value for RXTX_MAP in v1.2+.
> > > > Older implementations may still reject larger sizes, which can happen
> > > > when the minimum size is rounded up to the page size when PAGE_SIZE >
> > > > 4K.
> > > >
> > > > Fall back to the minimum size when RXTX_MAP fails with
> > > > INVALID_PARAMETERS to fix the regression on these platforms. This also
> > > > has the side effect of falling back for v1.2+ with a maximum of 0 (i.e.
> > > > no maximum), where the rounded-up value isn't expected to be rejected,
> > > > but there's no harm in retrying with a smaller size and it might even be
> > > > of benefit for a non-compliant SPMC.
> > > >
> > >
> > > Is this needed on any of your platforms ? I don't want to push a solution
> > > or fallback/workaround if there are no users for it.
> >
> > Yes, we have platforms for which commit 83210251fd70 causes RXTX_MAP
> > failures with page sizes larger than 4K.
> >
>
> And they are FF-A v1.1 or doesn't set max_buf size ? Sorry for being
> pedantic, just want to be sure it is useful on real platforms before
> pushing it as fix/workaround.
Yes, sorry, that's information I should have included. Some were v1.1,
don't set max buf size, and did fail with 64K pages. While I tested the
fix with 16K pages for thoroughness, I did not try to reproduce the
problem with that page size, so I can't say whether or not that would
succeed. But either way there's still a problem, and I figure that going
with the minimum size in that case is the surest bet.
Seth
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions
2026-06-01 20:45 [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Seth Forshee
2026-06-01 20:45 ` [PATCH 1/2] firmware: arm_ffa: Honor maximum RX/TX buffer size Seth Forshee
2026-06-01 20:45 ` [PATCH 2/2] firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails Seth Forshee
@ 2026-06-02 16:51 ` Sudeep Holla
2026-06-02 17:19 ` Seth Forshee
2 siblings, 1 reply; 14+ messages in thread
From: Sudeep Holla @ 2026-06-02 16:51 UTC (permalink / raw)
To: Seth Forshee; +Cc: Sebastian Ene, Sudeep Holla, linux-arm-kernel, linux-kernel
On Mon, Jun 01, 2026 at 03:45:10PM -0500, Seth Forshee wrote:
> Commit 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size
> during RXTX_MAP") caused a regression for some FF-A implementations. It
> has the effect of passing the size of the page-aligned buffers to
> FFA_RXTX_MAP, which may be larger than the maximum size supported by the
> SPMC. When this happens FFA_RXTX_MAP will fail with INVALID_PARAMETERS.
>
> The following patches deal with two distinct scenarios which lead to
> this issue. With FF-A v1.2+, FFA_FEATURES can specify a maximum supported
> RX/TX buffer size, so patch 1 decodes this field and honors the maximum if
> specified. For FF-A v1.1 and earlier the maximum is unknown, so patch 2
> deals with this by first attempting FFA_RXTX_MAP with the page-aligned
> buffer size (preserving the behavior introduced by commit 83210251fd70).
> If this fails due to invalid parameters it retries with the minimum buffer
> size from FFA_FEATURES.
>
> Testing was done with FF-A v1.1 and v1.2 implementations, both of which
> reject buffer sizes larger than 4K. Both implementations were tested with
> 4K, 16K, and 64K pages. Without these patches, probe fails for page sizes
> larger than 4K with the message "failed to register FFA RxTx buffers."
> With the patches probe succeeds for all page sizes.
>
> The patches are based on for-next/ffa/fixes.
for-next/ffa/updates has patches queued for v7.2.
>
> Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> ---
> Seth Forshee (2):
> firmware: arm_ffa: Honor maximum RX/TX buffer size
> firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
>
> drivers/firmware/arm_ffa/driver.c | 51 ++++++++++++++++++++++++++++++++++-----
> 1 file changed, 45 insertions(+), 6 deletions(-)
Wondering if these 2 fixes can be merged into one and simplified something
like(untested) patch below(rebased on linux-next or for-next/ffa/updates)
Regards,
Sudeep
-->8
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 0f468362c288..5ffe21c568b7 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -32,6 +32,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/mutex.h>
@@ -59,7 +60,9 @@
(FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
#define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
-#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
+#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
+#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
+#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
#define FFA_MAX_NOTIFICATIONS 64
@@ -2101,7 +2104,7 @@ static int ffa_probe(struct platform_device *pdev)
{
int ret;
u32 buf_sz;
- size_t rxtx_bufsz = SZ_4K;
+ size_t rxtx_min_bufsz = SZ_4K, rxtx_bufsz, rxtx_max_bufsz = 0;
if (IS_BUILTIN(CONFIG_ARM_FFA_TRANSPORT) &&
is_protected_kvm_enabled() && !is_pkvm_initialized())
@@ -2132,15 +2135,18 @@ static int ffa_probe(struct platform_device *pdev)
ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
if (!ret) {
if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
- rxtx_bufsz = SZ_64K;
+ rxtx_min_bufsz = SZ_64K;
else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
- rxtx_bufsz = SZ_16K;
+ rxtx_min_bufsz = SZ_16K;
else
- rxtx_bufsz = SZ_4K;
+ rxtx_min_bufsz = SZ_4K;
+
+ rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
+ if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
+ rxtx_max_bufsz = rxtx_min_bufsz;
}
- rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
- drv_info->rxtx_bufsz = rxtx_bufsz;
+ rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
if (!drv_info->rx_buffer) {
ret = -ENOMEM;
@@ -2156,10 +2162,17 @@ static int ffa_probe(struct platform_device *pdev)
ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
virt_to_phys(drv_info->rx_buffer),
rxtx_bufsz / FFA_PAGE_SIZE);
+ if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
+ rxtx_bufsz = rxtx_min_bufsz;
+ ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
+ virt_to_phys(drv_info->rx_buffer),
+ rxtx_bufsz / FFA_PAGE_SIZE);
+ }
if (ret) {
pr_err("failed to register FFA RxTx buffers\n");
goto free_pages;
}
+ drv_info->rxtx_bufsz = rxtx_bufsz;
mutex_init(&drv_info->rx_lock);
mutex_init(&drv_info->tx_lock);
^ permalink raw reply related [flat|nested] 14+ messages in thread* Re: [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions
2026-06-02 16:51 ` [PATCH 0/2] firmware: arm_ffa: Fix RXTX_MAP buffer size regressions Sudeep Holla
@ 2026-06-02 17:19 ` Seth Forshee
0 siblings, 0 replies; 14+ messages in thread
From: Seth Forshee @ 2026-06-02 17:19 UTC (permalink / raw)
To: Sudeep Holla; +Cc: Sebastian Ene, linux-arm-kernel, linux-kernel
On Tue, Jun 02, 2026 at 05:51:10PM +0100, Sudeep Holla wrote:
> On Mon, Jun 01, 2026 at 03:45:10PM -0500, Seth Forshee wrote:
> > Commit 83210251fd70 ("firmware: arm_ffa: Use the correct buffer size
> > during RXTX_MAP") caused a regression for some FF-A implementations. It
> > has the effect of passing the size of the page-aligned buffers to
> > FFA_RXTX_MAP, which may be larger than the maximum size supported by the
> > SPMC. When this happens FFA_RXTX_MAP will fail with INVALID_PARAMETERS.
> >
> > The following patches deal with two distinct scenarios which lead to
> > this issue. With FF-A v1.2+, FFA_FEATURES can specify a maximum supported
> > RX/TX buffer size, so patch 1 decodes this field and honors the maximum if
> > specified. For FF-A v1.1 and earlier the maximum is unknown, so patch 2
> > deals with this by first attempting FFA_RXTX_MAP with the page-aligned
> > buffer size (preserving the behavior introduced by commit 83210251fd70).
> > If this fails due to invalid parameters it retries with the minimum buffer
> > size from FFA_FEATURES.
> >
> > Testing was done with FF-A v1.1 and v1.2 implementations, both of which
> > reject buffer sizes larger than 4K. Both implementations were tested with
> > 4K, 16K, and 64K pages. Without these patches, probe fails for page sizes
> > larger than 4K with the message "failed to register FFA RxTx buffers."
> > With the patches probe succeeds for all page sizes.
> >
> > The patches are based on for-next/ffa/fixes.
>
> for-next/ffa/updates has patches queued for v7.2.
>
> >
> > Signed-off-by: Seth Forshee <sforshee@nvidia.com>
> > ---
> > Seth Forshee (2):
> > firmware: arm_ffa: Honor maximum RX/TX buffer size
> > firmware: arm_ffa: Fall back to minimum buffer size if RXTX_MAP fails
> >
> > drivers/firmware/arm_ffa/driver.c | 51 ++++++++++++++++++++++++++++++++++-----
> > 1 file changed, 45 insertions(+), 6 deletions(-)
>
> Wondering if these 2 fixes can be merged into one and simplified something
> like(untested) patch below(rebased on linux-next or for-next/ffa/updates)
From a quick review, yes, I think that looks like it should work. I'll
give it a closer look and some testing.
Seth
>
> Regards,
> Sudeep
>
> -->8
> diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
> index 0f468362c288..5ffe21c568b7 100644
> --- a/drivers/firmware/arm_ffa/driver.c
> +++ b/drivers/firmware/arm_ffa/driver.c
> @@ -32,6 +32,7 @@
> #include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> +#include <linux/minmax.h>
> #include <linux/module.h>
> #include <linux/mm.h>
> #include <linux/mutex.h>
> @@ -59,7 +60,9 @@
> (FIELD_PREP(SENDER_ID_MASK, (s)) | FIELD_PREP(RECEIVER_ID_MASK, (r)))
>
> #define RXTX_MAP_MIN_BUFSZ_MASK GENMASK(1, 0)
> -#define RXTX_MAP_MIN_BUFSZ(x) ((x) & RXTX_MAP_MIN_BUFSZ_MASK)
> +#define RXTX_MAP_MAX_BUFSZ_MASK GENMASK(31, 16)
> +#define RXTX_MAP_MIN_BUFSZ(x) (FIELD_GET(RXTX_MAP_MIN_BUFSZ_MASK, (x)))
> +#define RXTX_MAP_MAX_BUFSZ(x) (FIELD_GET(RXTX_MAP_MAX_BUFSZ_MASK, (x)))
>
> #define FFA_MAX_NOTIFICATIONS 64
>
> @@ -2101,7 +2104,7 @@ static int ffa_probe(struct platform_device *pdev)
> {
> int ret;
> u32 buf_sz;
> - size_t rxtx_bufsz = SZ_4K;
> + size_t rxtx_min_bufsz = SZ_4K, rxtx_bufsz, rxtx_max_bufsz = 0;
>
> if (IS_BUILTIN(CONFIG_ARM_FFA_TRANSPORT) &&
> is_protected_kvm_enabled() && !is_pkvm_initialized())
> @@ -2132,15 +2135,18 @@ static int ffa_probe(struct platform_device *pdev)
> ret = ffa_features(FFA_FN_NATIVE(RXTX_MAP), 0, &buf_sz, NULL);
> if (!ret) {
> if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 1)
> - rxtx_bufsz = SZ_64K;
> + rxtx_min_bufsz = SZ_64K;
> else if (RXTX_MAP_MIN_BUFSZ(buf_sz) == 2)
> - rxtx_bufsz = SZ_16K;
> + rxtx_min_bufsz = SZ_16K;
> else
> - rxtx_bufsz = SZ_4K;
> + rxtx_min_bufsz = SZ_4K;
> +
> + rxtx_max_bufsz = RXTX_MAP_MAX_BUFSZ(buf_sz) * SZ_4K;
> + if (rxtx_max_bufsz != 0 && rxtx_max_bufsz < rxtx_min_bufsz)
> + rxtx_max_bufsz = rxtx_min_bufsz;
> }
>
> - rxtx_bufsz = PAGE_ALIGN(rxtx_bufsz);
> - drv_info->rxtx_bufsz = rxtx_bufsz;
> + rxtx_bufsz = min_not_zero(PAGE_ALIGN(rxtx_min_bufsz), rxtx_max_bufsz);
> drv_info->rx_buffer = alloc_pages_exact(rxtx_bufsz, GFP_KERNEL);
> if (!drv_info->rx_buffer) {
> ret = -ENOMEM;
> @@ -2156,10 +2162,17 @@ static int ffa_probe(struct platform_device *pdev)
> ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
> virt_to_phys(drv_info->rx_buffer),
> rxtx_bufsz / FFA_PAGE_SIZE);
> + if (ret == -EINVAL && !rxtx_max_bufsz && rxtx_min_bufsz < rxtx_bufsz) {
> + rxtx_bufsz = rxtx_min_bufsz;
> + ret = ffa_rxtx_map(virt_to_phys(drv_info->tx_buffer),
> + virt_to_phys(drv_info->rx_buffer),
> + rxtx_bufsz / FFA_PAGE_SIZE);
> + }
> if (ret) {
> pr_err("failed to register FFA RxTx buffers\n");
> goto free_pages;
> }
> + drv_info->rxtx_bufsz = rxtx_bufsz;
>
> mutex_init(&drv_info->rx_lock);
> mutex_init(&drv_info->tx_lock);
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread