diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2025-10-23 22:29:39 +0200 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2025-10-23 22:29:50 +0200 |
| commit | f4cb02832060ffece6f2f49133592ce7054ac057 (patch) | |
| tree | 4260e790a815446e00b89580faff8c24e99f1ea2 /include/linux | |
| parent | 1d4e7d9f6b7e4e45ec8ca03ae1bbc6ae7165b6f0 (diff) | |
| parent | 11fb1a82aefa6f7fea6ac82334edb5639b9927df (diff) | |
Merge tag 'ffa-fix-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/fixes
Arm FF-A fix for v6.18
The FF-A driver was updated to support specification version 1.2 but omitted
support for the 16-byte implementation-defined (IMPDEF) field introduced in
FF-A v1.2 within the Endpoint Memory Access Descriptor (EMAD). This omission
breaks all memory interfaces.
This change updates the EMAD sizing and offset logic to correctly handle the
FF-A v1.2 layout while preserving backward compatibility with older versions.
* tag 'ffa-fix-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_ffa: Add support for IMPDEF value in the memory access descriptor
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/arm_ffa.h | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index cd7ee4df9045..81e603839c4a 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -338,6 +338,7 @@ struct ffa_mem_region_attributes { * an `struct ffa_mem_region_addr_range`. */ u32 composite_off; + u8 impdef_val[16]; u64 reserved; }; @@ -417,15 +418,31 @@ struct ffa_mem_region { #define CONSTITUENTS_OFFSET(x) \ (offsetof(struct ffa_composite_mem_region, constituents[x])) +#define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2) +#define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0) + +static inline u32 ffa_emad_size_get(u32 ffa_version) +{ + u32 sz; + struct ffa_mem_region_attributes *ep_mem_access; + + if (FFA_EMAD_HAS_IMPDEF_FIELD(ffa_version)) + sz = sizeof(*ep_mem_access); + else + sz = sizeof(*ep_mem_access) - sizeof(ep_mem_access->impdef_val); + + return sz; +} + static inline u32 ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version) { - u32 offset = count * sizeof(struct ffa_mem_region_attributes); + u32 offset = count * ffa_emad_size_get(ffa_version); /* * Earlier to v1.1, the endpoint memory descriptor array started at * offset 32(i.e. offset of ep_mem_offset in the current structure) */ - if (ffa_version <= FFA_VERSION_1_0) + if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version)) offset += offsetof(struct ffa_mem_region, ep_mem_offset); else offset += sizeof(struct ffa_mem_region); |
