mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-07 09:55:19 +02:00
KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer
commitf26a525b77
upstream. When we share memory through FF-A and the description of the buffers exceeds the size of the mapped buffer, the fragmentation API is used. The fragmentation API allows specifying chunks of descriptors in subsequent FF-A fragment calls and no upper limit has been established for this. The entire memory region transferred is identified by a handle which can be used to reclaim the transferred memory. To be able to reclaim the memory, the description of the buffers has to fit in the ffa_desc_buf. Add a bounds check on the FF-A sharing path to prevent the memory reclaim from failing. Also do_ffa_mem_xfer() does not need __always_inline, except for the BUILD_BUG_ON() aspect, which gets moved to a macro. [maz: fixed the BUILD_BUG_ON() breakage with LLVM, thanks to Wei-Lin Chang for the timely report] Fixes:634d90cf0a
("KVM: arm64: Handle FFA_MEM_LEND calls from the host") Cc: stable@vger.kernel.org Reviewed-by: Sebastian Ene <sebastianene@google.com> Signed-off-by: Snehal Koukuntla <snehalreddy@google.com> Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20240909180154.3267939-1-snehalreddy@google.com Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0188ea5fac
commit
d5d6489b92
|
@ -415,7 +415,7 @@ out:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void do_ffa_mem_xfer(const u64 func_id,
|
static void __do_ffa_mem_xfer(const u64 func_id,
|
||||||
struct arm_smccc_res *res,
|
struct arm_smccc_res *res,
|
||||||
struct kvm_cpu_context *ctxt)
|
struct kvm_cpu_context *ctxt)
|
||||||
{
|
{
|
||||||
|
@ -428,9 +428,6 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
|
||||||
u32 offset, nr_ranges;
|
u32 offset, nr_ranges;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
BUILD_BUG_ON(func_id != FFA_FN64_MEM_SHARE &&
|
|
||||||
func_id != FFA_FN64_MEM_LEND);
|
|
||||||
|
|
||||||
if (addr_mbz || npages_mbz || fraglen > len ||
|
if (addr_mbz || npages_mbz || fraglen > len ||
|
||||||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
|
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
|
||||||
ret = FFA_RET_INVALID_PARAMETERS;
|
ret = FFA_RET_INVALID_PARAMETERS;
|
||||||
|
@ -449,6 +446,11 @@ static __always_inline void do_ffa_mem_xfer(const u64 func_id,
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len > ffa_desc_buf.len) {
|
||||||
|
ret = FFA_RET_NO_MEMORY;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
buf = hyp_buffers.tx;
|
buf = hyp_buffers.tx;
|
||||||
memcpy(buf, host_buffers.tx, fraglen);
|
memcpy(buf, host_buffers.tx, fraglen);
|
||||||
|
|
||||||
|
@ -498,6 +500,13 @@ err_unshare:
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define do_ffa_mem_xfer(fid, res, ctxt) \
|
||||||
|
do { \
|
||||||
|
BUILD_BUG_ON((fid) != FFA_FN64_MEM_SHARE && \
|
||||||
|
(fid) != FFA_FN64_MEM_LEND); \
|
||||||
|
__do_ffa_mem_xfer((fid), (res), (ctxt)); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
|
static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
|
||||||
struct kvm_cpu_context *ctxt)
|
struct kvm_cpu_context *ctxt)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user