mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	crypto: af_alg: Support MSG_SPLICE_PAGES
Make AF_ALG sendmsg() support MSG_SPLICE_PAGES. This causes pages to be spliced from the source iterator. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells <dhowells@redhat.com> cc: Herbert Xu <herbert@gondor.apana.org.au> cc: "David S. Miller" <davem@davemloft.net> cc: Eric Dumazet <edumazet@google.com> cc: Jakub Kicinski <kuba@kernel.org> cc: Paolo Abeni <pabeni@redhat.com> cc: Jens Axboe <axboe@kernel.dk> cc: Matthew Wilcox <willy@infradead.org> cc: linux-crypto@vger.kernel.org cc: netdev@vger.kernel.org Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
		
							parent
							
								
									73d7409cfd
								
							
						
					
					
						commit
						bf63e250c4
					
				
					 3 changed files with 37 additions and 17 deletions
				
			
		| 
						 | 
					@ -985,7 +985,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
 | 
				
			||||||
	while (size) {
 | 
						while (size) {
 | 
				
			||||||
		struct scatterlist *sg;
 | 
							struct scatterlist *sg;
 | 
				
			||||||
		size_t len = size;
 | 
							size_t len = size;
 | 
				
			||||||
		size_t plen;
 | 
							ssize_t plen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* use the existing memory in an allocated page */
 | 
							/* use the existing memory in an allocated page */
 | 
				
			||||||
		if (ctx->merge) {
 | 
							if (ctx->merge) {
 | 
				
			||||||
| 
						 | 
					@ -1030,7 +1030,27 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
 | 
				
			||||||
		if (sgl->cur)
 | 
							if (sgl->cur)
 | 
				
			||||||
			sg_unmark_end(sg + sgl->cur - 1);
 | 
								sg_unmark_end(sg + sgl->cur - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (1 /* TODO check MSG_SPLICE_PAGES */) {
 | 
							if (msg->msg_flags & MSG_SPLICE_PAGES) {
 | 
				
			||||||
 | 
								struct sg_table sgtable = {
 | 
				
			||||||
 | 
									.sgl		= sg,
 | 
				
			||||||
 | 
									.nents		= sgl->cur,
 | 
				
			||||||
 | 
									.orig_nents	= sgl->cur,
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable,
 | 
				
			||||||
 | 
											  MAX_SGL_ENTS, 0);
 | 
				
			||||||
 | 
								if (plen < 0) {
 | 
				
			||||||
 | 
									err = plen;
 | 
				
			||||||
 | 
									goto unlock;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (; sgl->cur < sgtable.nents; sgl->cur++)
 | 
				
			||||||
 | 
									get_page(sg_page(&sg[sgl->cur]));
 | 
				
			||||||
 | 
								len -= plen;
 | 
				
			||||||
 | 
								ctx->used += plen;
 | 
				
			||||||
 | 
								copied += plen;
 | 
				
			||||||
 | 
								size -= plen;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
			do {
 | 
								do {
 | 
				
			||||||
				struct page *pg;
 | 
									struct page *pg;
 | 
				
			||||||
				unsigned int i = sgl->cur;
 | 
									unsigned int i = sgl->cur;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,8 +9,8 @@
 | 
				
			||||||
 * The following concept of the memory management is used:
 | 
					 * The following concept of the memory management is used:
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
 | 
					 * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
 | 
				
			||||||
 * filled by user space with the data submitted via sendpage/sendmsg. Filling
 | 
					 * filled by user space with the data submitted via sendpage. Filling up
 | 
				
			||||||
 * up the TX SGL does not cause a crypto operation -- the data will only be
 | 
					 * the TX SGL does not cause a crypto operation -- the data will only be
 | 
				
			||||||
 * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
 | 
					 * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
 | 
				
			||||||
 * provide a buffer which is tracked with the RX SGL.
 | 
					 * provide a buffer which is tracked with the RX SGL.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -113,19 +113,19 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Data length provided by caller via sendmsg/sendpage that has not
 | 
						 * Data length provided by caller via sendmsg that has not yet been
 | 
				
			||||||
	 * yet been processed.
 | 
						 * processed.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	used = ctx->used;
 | 
						used = ctx->used;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Make sure sufficient data is present -- note, the same check is
 | 
						 * Make sure sufficient data is present -- note, the same check is also
 | 
				
			||||||
	 * also present in sendmsg/sendpage. The checks in sendpage/sendmsg
 | 
						 * present in sendmsg. The checks in sendmsg shall provide an
 | 
				
			||||||
	 * shall provide an information to the data sender that something is
 | 
						 * information to the data sender that something is wrong, but they are
 | 
				
			||||||
	 * wrong, but they are irrelevant to maintain the kernel integrity.
 | 
						 * irrelevant to maintain the kernel integrity.  We need this check
 | 
				
			||||||
	 * We need this check here too in case user space decides to not honor
 | 
						 * here too in case user space decides to not honor the error message
 | 
				
			||||||
	 * the error message in sendmsg/sendpage and still call recvmsg. This
 | 
						 * in sendmsg and still call recvmsg. This check here protects the
 | 
				
			||||||
	 * check here protects the kernel integrity.
 | 
						 * kernel integrity.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!aead_sufficient_data(sk))
 | 
						if (!aead_sufficient_data(sk))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,10 +9,10 @@
 | 
				
			||||||
 * The following concept of the memory management is used:
 | 
					 * The following concept of the memory management is used:
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
 | 
					 * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is
 | 
				
			||||||
 * filled by user space with the data submitted via sendpage/sendmsg. Filling
 | 
					 * filled by user space with the data submitted via sendmsg. Filling up the TX
 | 
				
			||||||
 * up the TX SGL does not cause a crypto operation -- the data will only be
 | 
					 * SGL does not cause a crypto operation -- the data will only be tracked by
 | 
				
			||||||
 * tracked by the kernel. Upon receipt of one recvmsg call, the caller must
 | 
					 * the kernel. Upon receipt of one recvmsg call, the caller must provide a
 | 
				
			||||||
 * provide a buffer which is tracked with the RX SGL.
 | 
					 * buffer which is tracked with the RX SGL.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * During the processing of the recvmsg operation, the cipher request is
 | 
					 * During the processing of the recvmsg operation, the cipher request is
 | 
				
			||||||
 * allocated and prepared. As part of the recvmsg operation, the processed
 | 
					 * allocated and prepared. As part of the recvmsg operation, the processed
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue