Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors

The transmit buffers allocated by the driver can be used to transmit data
by any messages/commands needing the buffer. However, it is not guaranteed
to have been zero-ed before every new transmission and hence it will just
contain residual value from the previous transmission. There are several
reserved fields in the memory descriptors that must be zero(MBZ). The
receiver can reject the transmission if any such MBZ fields are non-zero.

While we can set the whole page to zero, it is not optimal as most of the
fields get initialised to the value required for the current transmission.

So, just set the reserved/MBZ fields to zero in the memory descriptors
explicitly to honour the requirement and keep the receiver happy.

Fixes: cc2195fe536c ("firmware: arm_ffa: Add support for MEM_* interfaces")
Reported-by: Marc Bonnici <marc.bonnici@arm.com>
Link: https://lore.kernel.org/r/20230503131252.12585-1-sudeep.holla@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>

+6
+6
drivers/firmware/arm_ffa/driver.c
··· 421 421 ep_mem_access->receiver = args->attrs[idx].receiver; 422 422 ep_mem_access->attrs = args->attrs[idx].attrs; 423 423 ep_mem_access->composite_off = COMPOSITE_OFFSET(args->nattrs); 424 + ep_mem_access->flag = 0; 425 + ep_mem_access->reserved = 0; 424 426 } 427 + mem_region->reserved_0 = 0; 428 + mem_region->reserved_1 = 0; 425 429 mem_region->ep_count = args->nattrs; 426 430 427 431 composite = buffer + COMPOSITE_OFFSET(args->nattrs); 428 432 composite->total_pg_cnt = ffa_get_num_pages_sg(args->sg); 429 433 composite->addr_range_cnt = num_entries; 434 + composite->reserved = 0; 430 435 431 436 length = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, num_entries); 432 437 frag_len = COMPOSITE_CONSTITUENTS_OFFSET(args->nattrs, 0); ··· 466 461 467 462 constituents->address = sg_phys(args->sg); 468 463 constituents->pg_cnt = args->sg->length / FFA_PAGE_SIZE; 464 + constituents->reserved = 0; 469 465 constituents++; 470 466 frag_len += sizeof(struct ffa_mem_region_addr_range); 471 467 } while ((args->sg = sg_next(args->sg)));