From c91cd1264a70252e69c05237be02557616786d59 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 18 Jul 2022 14:44:32 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Increase size of FF-A buffer As it turns out, the kernel's DMA code doesn't enforce the SG_MAX_SEGMENTS limit on the number of elements in an sglist, which can confuse the pKVM FF-A proxy which has a buffer sized to contain a descriptor of at most SG_MAX_SEGMENTS constituents. As the number of elements in an sglist doesn't seem to have an actual upper bound, let's paper over the issue for now by increasing the size of the pKVM buffer based on empirical 'measurements'. Longer term we might need to make this value configurable on the kernel's cmdline, or to rework the FF-A proxy to sanely handle large descriptors, although this is not clear how at the time of writing. Bug: 221256863 Signed-off-by: Quentin Perret Change-Id: If252f01bec8ae71c0fe1f7007a3ca7b037924c84 --- arch/arm64/include/asm/kvm_pkvm.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index 708d6d5c27f4..7ac74dd69b34 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -335,10 +335,27 @@ static inline unsigned long host_s2_pgtable_pages(void) #define KVM_FFA_MBOX_NR_PAGES 1 +/* + * Maximum number of consitutents allowed in a descriptor. This number is + * arbitrary, see comment below on SG_MAX_SEGMENTS in hyp_ffa_proxy_pages(). + */ +#define KVM_FFA_MAX_NR_CONSTITUENTS 4096 + static inline unsigned long hyp_ffa_proxy_pages(void) { size_t desc_max; + /* + * SG_MAX_SEGMENTS is supposed to bound the number of elements in an + * sglist, which should match the number of consituents in the + * corresponding FFA descriptor. As such, the EL2 buffer needs to be + * large enough to hold a descriptor with SG_MAX_SEGMENTS consituents + * at least. But the kernel's DMA code doesn't enforce the limit, and + * it is sometimes abused, so let's allow larger descriptors and hope + * for the best. + */ + BUILD_BUG_ON(KVM_FFA_MAX_NR_CONSTITUENTS < SG_MAX_SEGMENTS); + /* * The hypervisor FFA proxy needs enough memory to buffer a fragmented * descriptor returned from EL3 in response to a RETRIEVE_REQ call. @@ -346,7 +363,7 @@ static inline unsigned long hyp_ffa_proxy_pages(void) desc_max = sizeof(struct ffa_mem_region) + sizeof(struct ffa_mem_region_attributes) + sizeof(struct ffa_composite_mem_region) + - SG_MAX_SEGMENTS * sizeof(struct ffa_mem_region_addr_range); + KVM_FFA_MAX_NR_CONSTITUENTS * sizeof(struct ffa_mem_region_addr_range); /* Plus a page each for the hypervisor's RX and TX mailboxes. */ return (2 * KVM_FFA_MBOX_NR_PAGES) + DIV_ROUND_UP(desc_max, PAGE_SIZE);