diff options
author | Marc Bonnici <marc.bonnici@arm.com> | 2021-09-15 10:43:47 +0100 |
---|---|---|
committer | Marc Bonnici <marc.bonnici@arm.com> | 2021-10-07 15:48:25 +0100 |
commit | 0f8fa92d6c2663bdd3c0a176c60a9f11f7df25fe (patch) | |
tree | d308843ddbd3e48df02ad6b8736701932a0cf361 | |
parent | 3e78a9e55f2b0af1434ac9f5a4d44d0733b45f77 (diff) | |
download | trusted-firmware-a-0f8fa92d6c2663bdd3c0a176c60a9f11f7df25fe.tar.gz |
spmc: Update mailbox buffers to pointers
To be inline with other SPMC implementations switch to
using pointers for storing a partitions RX and TX buffers.
Update the existing implementation to support this and
fix error handling.
Change-Id: Ie16995d3b197b724da23604a8bcd961dd295a164
Signed-off-by: Marc Bonnici <marc.bonnici@arm.com>
-rw-r--r-- | services/std_svc/spm/spmc/spmc.h | 6 | ||||
-rw-r--r-- | services/std_svc/spm/spmc/spmc_main.c | 44 |
2 files changed, 29 insertions, 21 deletions
diff --git a/services/std_svc/spm/spmc/spmc.h b/services/std_svc/spm/spmc/spmc.h index 04908bcc91..b998603d7b 100644 --- a/services/std_svc/spm/spmc/spmc.h +++ b/services/std_svc/spm/spmc/spmc.h @@ -28,6 +28,8 @@ #define FFA_SP_ID_BASE (FFA_SPMC_ID + 1) /* SP IDs are allocated after the SPMC ID */ #define INV_SP_ID 0x7FFF /* Align with Hafnium implementation */ +#define FFA_PAGE_SIZE (4096) + /* * Runtime states of an execution context as per the FF-A v1.1 specification. */ @@ -69,8 +71,8 @@ struct mailbox { enum mailbox_state state; /* RX/TX Buffers */ - uintptr_t rx_buffer; - uintptr_t tx_buffer; + void *rx_buffer; + const void *tx_buffer; /* * Size of RX/TX Buffer diff --git a/services/std_svc/spm/spmc/spmc_main.c b/services/std_svc/spm/spmc/spmc_main.c index 45f9820f98..8b90edd2f7 100644 --- a/services/std_svc/spm/spmc/spmc_main.c +++ b/services/std_svc/spm/spmc/spmc_main.c @@ -373,13 +373,18 @@ static uint64_t rxtx_map_handler(uint32_t smc_fid, uint32_t mem_atts = secure_origin ? MT_SECURE : MT_NS; struct mailbox *mbox; + uintptr_t tx_address = x1; + uintptr_t rx_address = x2; + uint32_t page_count = (uint32_t) x3 & 0x1F; /* Bits [5:0] */ + uint32_t buf_size = page_count * FFA_PAGE_SIZE; + /* * The SPMC does not support mapping of VM RX/TX pairs to facilitate * indirect messaging with SPs. Check if the Hypervisor has invoked this * ABI on behalf of a VM and reject it if this is the case. * TODO: Check FF-A spec guidance on this scenario. */ - if (x1 == 0 || x2 == 0) { + if (tx_address == 0 || rx_address == 0 ) { return spmc_ffa_error_return(handle, FFA_ERROR_INVALID_PARAMETER); } @@ -390,30 +395,29 @@ static uint64_t rxtx_map_handler(uint32_t smc_fid, /* Check if buffers have already been mapped. */ if (mbox->rx_buffer != 0 || mbox->tx_buffer != 0) { - WARN("%p %p\n", (void *) mbox->rx_buffer, (void *)mbox->tx_buffer); - return spmc_ffa_error_return(handle, FFA_ERROR_DENIED); + WARN("RX/TX Buffers already mapped (%p/%p)\n", (void *) mbox->rx_buffer, (void *)mbox->tx_buffer); + error_code = FFA_ERROR_DENIED; + goto err; } - mbox->rxtx_page_count = x3 & 0x1F; /* Bits [5:0] */ - /* memmap the TX buffer as read only. */ - ret = mmap_add_dynamic_region(x1, /* PA */ - x1, /* VA */ - PAGE_SIZE * mbox->rxtx_page_count, /* size */ + ret = mmap_add_dynamic_region(tx_address, /* PA */ + tx_address, /* VA */ + buf_size, /* size */ mem_atts | MT_RO_DATA); /* attrs */ if (ret) { /* Return the correct error code. */ error_code = (ret == -ENOMEM) ? FFA_ERROR_NO_MEMORY : FFA_ERROR_INVALID_PARAMETER; WARN("Unable to map TX buffer: %d\n", error_code); mbox->rxtx_page_count = 0; - return spmc_ffa_error_return(handle, error_code); + goto err; } - mbox->tx_buffer = x1; + mbox->tx_buffer = (void *) tx_address; /* memmap the RX buffer as read write. */ - ret = mmap_add_dynamic_region(x2, /* PA */ - x2, /* VA */ - PAGE_SIZE * mbox->rxtx_page_count, /* size */ + ret = mmap_add_dynamic_region(rx_address, /* PA */ + rx_address, /* VA */ + buf_size, /* size */ mem_atts | MT_RW_DATA); /* attrs */ if (ret) { @@ -421,16 +425,17 @@ static uint64_t rxtx_map_handler(uint32_t smc_fid, WARN("Unable to map RX buffer: %d\n", error_code); goto err_unmap; } - mbox->rx_buffer = x2; + mbox->rx_buffer = (void *) rx_address; + mbox->rxtx_page_count = page_count; spin_unlock(&mbox->lock); SMC_RET1(handle, FFA_SUCCESS_SMC32); err_unmap: /* Unmap the TX buffer again. */ - (void)mmap_remove_dynamic_region(mbox->tx_buffer, PAGE_SIZE * mbox->rxtx_page_count); + mmap_remove_dynamic_region(tx_address, buf_size); +err: mbox->tx_buffer = 0; - mbox->rxtx_page_count = 0; spin_unlock(&mbox->lock); return spmc_ffa_error_return(handle, error_code); @@ -447,6 +452,7 @@ static uint64_t rxtx_unmap_handler(uint32_t smc_fid, uint64_t flags) { struct mailbox *mbox = spmc_get_mbox_desc(flags); + uint32_t buf_size = mbox->rxtx_page_count * FFA_PAGE_SIZE; /* * The SPMC does not support mapping of VM RX/TX pairs to facilitate @@ -461,17 +467,17 @@ static uint64_t rxtx_unmap_handler(uint32_t smc_fid, spin_lock(&mbox->lock); /* Check if buffers have already been mapped. */ - if (mbox->rx_buffer != 0 || mbox->tx_buffer != 0) { + if (mbox->rx_buffer == 0 || mbox->tx_buffer == 0) { spin_unlock(&mbox->lock); return spmc_ffa_error_return(handle, FFA_ERROR_DENIED); } /* unmap RX Buffer */ - (void)mmap_remove_dynamic_region(mbox->rx_buffer, PAGE_SIZE * mbox->rxtx_page_count); + mmap_remove_dynamic_region((uintptr_t) mbox->rx_buffer, buf_size); mbox->rx_buffer = 0; /* unmap TX Buffer */ - (void)mmap_remove_dynamic_region(mbox->tx_buffer, PAGE_SIZE * mbox->rxtx_page_count); + mmap_remove_dynamic_region((uintptr_t) mbox->tx_buffer, buf_size); mbox->tx_buffer = 0; spin_unlock(&mbox->lock); |