aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Bonnici <marc.bonnici@arm.com>2021-09-15 10:43:47 +0100
committerMarc Bonnici <marc.bonnici@arm.com>2021-10-07 15:48:25 +0100
commit0f8fa92d6c2663bdd3c0a176c60a9f11f7df25fe (patch)
treed308843ddbd3e48df02ad6b8736701932a0cf361
parent3e78a9e55f2b0af1434ac9f5a4d44d0733b45f77 (diff)
downloadtrusted-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.h6
-rw-r--r--services/std_svc/spm/spmc/spmc_main.c44
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);