Previously all data passed over binder needed to be serialized, with the exception of Binder objects and file descriptors. This patchs adds support for scatter-gathering raw memory buffers into a binder transaction, avoiding the need to first serialize them into a Parcel. To remain backwards compatibile with existing binder clients, it introduces two new command ioctls for this purpose - BC_TRANSACTION_SG and BC_REPLY_SG. These commands may only be used with the new binder_transaction_data_sg structure, which adds a field for the total size of the buffers we are scatter-gathering. Because memory buffers may contain pointers to other buffers, we allow callers to specify a parent buffer and an offset into it, to indicate this is a location pointing to the buffer that we are fixing up. The kernel will then take care of fixing up the pointer to that buffer as well.
Showing the changes to include/uapi/linux (1 of 2 files). Show all
Unified · Split
| @@ -33,6 +33,7 @@ enum { · 32 unmodified lines | |||
| 33 | BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), | 33 | BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), |
| 34 | BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), | 34 | BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), |
| 35 | BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), | 35 | BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), |
| 36 | BINDER_TYPE_PTR = B_PACK_CHARS('p', 't', '*', B_TYPE_LARGE), | ||
| 36 | }; | 37 | }; |
| 37 | 38 | ||
| 38 | enum { | 39 | enum { |
| @@ -95,6 +96,39 @@ struct binder_fd_object { · 56 unmodified lines | |||
| 95 | 96 | ||
| 96 | binder_uintptr_t cookie; | 97 | binder_uintptr_t cookie; |
| 97 | }; | 98 | }; |
| 99 | |||
| 100 | /* struct binder_buffer_object - object describing a userspace buffer | ||
| 101 | * @hdr: common header structure | ||
| 102 | * @flags: one or more BINDER_BUFFER_* flags | ||
| 103 | * @buffer: address of the buffer | ||
| 104 | * @length: length of the buffer | ||
| 105 | * @parent: index in offset array pointing to parent buffer | ||
| 106 | * @parent_offset: offset in @parent pointing to this buffer | ||
| 107 | * | ||
| 108 | * A binder_buffer object represents an object that the | ||
| 109 | * binder kernel driver can copy verbatim to the target | ||
| 110 | * address space. A buffer itself may be pointed to from | ||
| 111 | * within another buffer, meaning that the pointer inside | ||
| 112 | * that other buffer needs to be fixed up as well. This | ||
| 113 | * can be done by setting the BINDER_BUFFER_FLAG_HAS_PARENT | ||
| 114 | * flag in @flags, by setting @parent buffer to the index | ||
| 115 | * in the offset array pointing to the parent binder_buffer_object, | ||
| 116 | * and by setting @parent_offset to the offset in the parent buffer | ||
| 117 | * at which the pointer to this buffer is located. | ||
| 118 | */ | ||
| 119 | struct binder_buffer_object { | ||
| 120 | struct binder_object_header hdr; | ||
| 121 | __u32 flags; | ||
| 122 | binder_uintptr_t buffer; | ||
| 123 | binder_size_t length; | ||
| 124 | binder_size_t parent; | ||
| 125 | binder_size_t parent_offset; | ||
| 126 | }; | ||
| 127 | |||
| 128 | enum { | ||
| 129 | BINDER_BUFFER_FLAG_HAS_PARENT = 0x01, | ||
| 130 | }; | ||
| 131 | |||
| 98 | /* | 132 | /* |
| 99 | * On 64-bit platforms where user code may run in 32-bits the driver must | 133 | * On 64-bit platforms where user code may run in 32-bits the driver must |
| 100 | * translate the buffer (and local binder) addresses appropriately. | 134 | * translate the buffer (and local binder) addresses appropriately. |
| @@ -187,6 +221,11 @@ struct binder_transaction_data { · 86 unmodified lines | |||
| 187 | } data; | 221 | } data; |
| 188 | }; | 222 | }; |
| 189 | 223 | ||
| 224 | struct binder_transaction_data_sg { | ||
| 225 | struct binder_transaction_data transaction_data; | ||
| 226 | binder_size_t buffers_size; | ||
| 227 | }; | ||
| 228 | |||
| 190 | struct binder_ptr_cookie { | 229 | struct binder_ptr_cookie { |
| 191 | binder_uintptr_t ptr; | 230 | binder_uintptr_t ptr; |
| 192 | binder_uintptr_t cookie; | 231 | binder_uintptr_t cookie; |
| @@ -371,6 +410,12 @@ enum binder_driver_command_protocol { · 178 unmodified lines | |||
| 371 | /* | 410 | /* |
| 372 | * void *: cookie | 411 | * void *: cookie |
| 373 | */ | 412 | */ |
| 413 | |||
| 414 | BC_TRANSACTION_SG = _IOW('c', 17, struct binder_transaction_data_sg), | ||
| 415 | BC_REPLY_SG = _IOW('c', 18, struct binder_transaction_data_sg), | ||
| 416 | /* | ||
| 417 | * binder_transaction_data_sg: the sent command. | ||
| 418 | */ | ||
| 374 | }; | 419 | }; |
| 375 | 420 | ||
| 376 | #endif /* _UAPI_LINUX_BINDER_H */ | 421 | #endif /* _UAPI_LINUX_BINDER_H */ |