162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2017 Google, Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _LINUX_BINDER_ALLOC_H
762306a36Sopenharmony_ci#define _LINUX_BINDER_ALLOC_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/rbtree.h>
1062306a36Sopenharmony_ci#include <linux/list.h>
1162306a36Sopenharmony_ci#include <linux/mm.h>
1262306a36Sopenharmony_ci#include <linux/rtmutex.h>
1362306a36Sopenharmony_ci#include <linux/vmalloc.h>
1462306a36Sopenharmony_ci#include <linux/slab.h>
1562306a36Sopenharmony_ci#include <linux/list_lru.h>
1662306a36Sopenharmony_ci#include <uapi/linux/android/binder.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciextern struct list_lru binder_alloc_lru;
1962306a36Sopenharmony_cistruct binder_transaction;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/**
2262306a36Sopenharmony_ci * struct binder_buffer - buffer used for binder transactions
2362306a36Sopenharmony_ci * @entry:              entry alloc->buffers
2462306a36Sopenharmony_ci * @rb_node:            node for allocated_buffers/free_buffers rb trees
2562306a36Sopenharmony_ci * @free:               %true if buffer is free
2662306a36Sopenharmony_ci * @clear_on_free:      %true if buffer must be zeroed after use
2762306a36Sopenharmony_ci * @allow_user_free:    %true if user is allowed to free buffer
2862306a36Sopenharmony_ci * @async_transaction:  %true if buffer is in use for an async txn
2962306a36Sopenharmony_ci * @oneway_spam_suspect: %true if total async allocate size just exceed
3062306a36Sopenharmony_ci * spamming detect threshold
3162306a36Sopenharmony_ci * @debug_id:           unique ID for debugging
3262306a36Sopenharmony_ci * @transaction:        pointer to associated struct binder_transaction
3362306a36Sopenharmony_ci * @target_node:        struct binder_node associated with this buffer
3462306a36Sopenharmony_ci * @data_size:          size of @transaction data
3562306a36Sopenharmony_ci * @offsets_size:       size of array of offsets
3662306a36Sopenharmony_ci * @extra_buffers_size: size of space for other objects (like sg lists)
3762306a36Sopenharmony_ci * @user_data:          user pointer to base of buffer space
3862306a36Sopenharmony_ci * @pid:                pid to attribute the buffer to (caller)
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci * Bookkeeping structure for binder transaction buffers
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_cistruct binder_buffer {
4362306a36Sopenharmony_ci	struct list_head entry; /* free and allocated entries by address */
4462306a36Sopenharmony_ci	struct rb_node rb_node; /* free entry by size or allocated entry */
4562306a36Sopenharmony_ci				/* by address */
4662306a36Sopenharmony_ci	unsigned free:1;
4762306a36Sopenharmony_ci	unsigned clear_on_free:1;
4862306a36Sopenharmony_ci	unsigned allow_user_free:1;
4962306a36Sopenharmony_ci	unsigned async_transaction:1;
5062306a36Sopenharmony_ci	unsigned oneway_spam_suspect:1;
5162306a36Sopenharmony_ci	unsigned debug_id:27;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	struct binder_transaction *transaction;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	struct binder_node *target_node;
5662306a36Sopenharmony_ci	size_t data_size;
5762306a36Sopenharmony_ci	size_t offsets_size;
5862306a36Sopenharmony_ci	size_t extra_buffers_size;
5962306a36Sopenharmony_ci	void __user *user_data;
6062306a36Sopenharmony_ci	int    pid;
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/**
6462306a36Sopenharmony_ci * struct binder_lru_page - page object used for binder shrinker
6562306a36Sopenharmony_ci * @page_ptr: pointer to physical page in mmap'd space
6662306a36Sopenharmony_ci * @lru:      entry in binder_alloc_lru
6762306a36Sopenharmony_ci * @alloc:    binder_alloc for a proc
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_cistruct binder_lru_page {
7062306a36Sopenharmony_ci	struct list_head lru;
7162306a36Sopenharmony_ci	struct page *page_ptr;
7262306a36Sopenharmony_ci	struct binder_alloc *alloc;
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci/**
7662306a36Sopenharmony_ci * struct binder_alloc - per-binder proc state for binder allocator
7762306a36Sopenharmony_ci * @mutex:              protects binder_alloc fields
7862306a36Sopenharmony_ci * @vma:                vm_area_struct passed to mmap_handler
7962306a36Sopenharmony_ci *                      (invariant after mmap)
8062306a36Sopenharmony_ci * @mm:                 copy of task->mm (invariant after open)
8162306a36Sopenharmony_ci * @buffer:             base of per-proc address space mapped via mmap
8262306a36Sopenharmony_ci * @buffers:            list of all buffers for this proc
8362306a36Sopenharmony_ci * @free_buffers:       rb tree of buffers available for allocation
8462306a36Sopenharmony_ci *                      sorted by size
8562306a36Sopenharmony_ci * @allocated_buffers:  rb tree of allocated buffers sorted by address
8662306a36Sopenharmony_ci * @free_async_space:   VA space available for async buffers. This is
8762306a36Sopenharmony_ci *                      initialized at mmap time to 1/2 the full VA space
8862306a36Sopenharmony_ci * @pages:              array of binder_lru_page
8962306a36Sopenharmony_ci * @buffer_size:        size of address space specified via mmap
9062306a36Sopenharmony_ci * @pid:                pid for associated binder_proc (invariant after init)
9162306a36Sopenharmony_ci * @pages_high:         high watermark of offset in @pages
9262306a36Sopenharmony_ci * @oneway_spam_detected: %true if oneway spam detection fired, clear that
9362306a36Sopenharmony_ci * flag once the async buffer has returned to a healthy state
9462306a36Sopenharmony_ci *
9562306a36Sopenharmony_ci * Bookkeeping structure for per-proc address space management for binder
9662306a36Sopenharmony_ci * buffers. It is normally initialized during binder_init() and binder_mmap()
9762306a36Sopenharmony_ci * calls. The address space is used for both user-visible buffers and for
9862306a36Sopenharmony_ci * struct binder_buffer objects used to track the user buffers
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_cistruct binder_alloc {
10162306a36Sopenharmony_ci	struct mutex mutex;
10262306a36Sopenharmony_ci	struct vm_area_struct *vma;
10362306a36Sopenharmony_ci	struct mm_struct *mm;
10462306a36Sopenharmony_ci	void __user *buffer;
10562306a36Sopenharmony_ci	struct list_head buffers;
10662306a36Sopenharmony_ci	struct rb_root free_buffers;
10762306a36Sopenharmony_ci	struct rb_root allocated_buffers;
10862306a36Sopenharmony_ci	size_t free_async_space;
10962306a36Sopenharmony_ci	struct binder_lru_page *pages;
11062306a36Sopenharmony_ci	size_t buffer_size;
11162306a36Sopenharmony_ci	int pid;
11262306a36Sopenharmony_ci	size_t pages_high;
11362306a36Sopenharmony_ci	bool oneway_spam_detected;
11462306a36Sopenharmony_ci};
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST
11762306a36Sopenharmony_civoid binder_selftest_alloc(struct binder_alloc *alloc);
11862306a36Sopenharmony_ci#else
11962306a36Sopenharmony_cistatic inline void binder_selftest_alloc(struct binder_alloc *alloc) {}
12062306a36Sopenharmony_ci#endif
12162306a36Sopenharmony_cienum lru_status binder_alloc_free_page(struct list_head *item,
12262306a36Sopenharmony_ci				       struct list_lru_one *lru,
12362306a36Sopenharmony_ci				       spinlock_t *lock, void *cb_arg);
12462306a36Sopenharmony_ciextern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc,
12562306a36Sopenharmony_ci						  size_t data_size,
12662306a36Sopenharmony_ci						  size_t offsets_size,
12762306a36Sopenharmony_ci						  size_t extra_buffers_size,
12862306a36Sopenharmony_ci						  int is_async,
12962306a36Sopenharmony_ci						  int pid);
13062306a36Sopenharmony_ciextern void binder_alloc_init(struct binder_alloc *alloc);
13162306a36Sopenharmony_ciextern int binder_alloc_shrinker_init(void);
13262306a36Sopenharmony_ciextern void binder_alloc_shrinker_exit(void);
13362306a36Sopenharmony_ciextern void binder_alloc_vma_close(struct binder_alloc *alloc);
13462306a36Sopenharmony_ciextern struct binder_buffer *
13562306a36Sopenharmony_cibinder_alloc_prepare_to_free(struct binder_alloc *alloc,
13662306a36Sopenharmony_ci			     uintptr_t user_ptr);
13762306a36Sopenharmony_ciextern void binder_alloc_free_buf(struct binder_alloc *alloc,
13862306a36Sopenharmony_ci				  struct binder_buffer *buffer);
13962306a36Sopenharmony_ciextern int binder_alloc_mmap_handler(struct binder_alloc *alloc,
14062306a36Sopenharmony_ci				     struct vm_area_struct *vma);
14162306a36Sopenharmony_ciextern void binder_alloc_deferred_release(struct binder_alloc *alloc);
14262306a36Sopenharmony_ciextern int binder_alloc_get_allocated_count(struct binder_alloc *alloc);
14362306a36Sopenharmony_ciextern void binder_alloc_print_allocated(struct seq_file *m,
14462306a36Sopenharmony_ci					 struct binder_alloc *alloc);
14562306a36Sopenharmony_civoid binder_alloc_print_pages(struct seq_file *m,
14662306a36Sopenharmony_ci			      struct binder_alloc *alloc);
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/**
14962306a36Sopenharmony_ci * binder_alloc_get_free_async_space() - get free space available for async
15062306a36Sopenharmony_ci * @alloc:	binder_alloc for this proc
15162306a36Sopenharmony_ci *
15262306a36Sopenharmony_ci * Return:	the bytes remaining in the address-space for async transactions
15362306a36Sopenharmony_ci */
15462306a36Sopenharmony_cistatic inline size_t
15562306a36Sopenharmony_cibinder_alloc_get_free_async_space(struct binder_alloc *alloc)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	size_t free_async_space;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	mutex_lock(&alloc->mutex);
16062306a36Sopenharmony_ci	free_async_space = alloc->free_async_space;
16162306a36Sopenharmony_ci	mutex_unlock(&alloc->mutex);
16262306a36Sopenharmony_ci	return free_async_space;
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ciunsigned long
16662306a36Sopenharmony_cibinder_alloc_copy_user_to_buffer(struct binder_alloc *alloc,
16762306a36Sopenharmony_ci				 struct binder_buffer *buffer,
16862306a36Sopenharmony_ci				 binder_size_t buffer_offset,
16962306a36Sopenharmony_ci				 const void __user *from,
17062306a36Sopenharmony_ci				 size_t bytes);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ciint binder_alloc_copy_to_buffer(struct binder_alloc *alloc,
17362306a36Sopenharmony_ci				struct binder_buffer *buffer,
17462306a36Sopenharmony_ci				binder_size_t buffer_offset,
17562306a36Sopenharmony_ci				void *src,
17662306a36Sopenharmony_ci				size_t bytes);
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ciint binder_alloc_copy_from_buffer(struct binder_alloc *alloc,
17962306a36Sopenharmony_ci				  void *dest,
18062306a36Sopenharmony_ci				  struct binder_buffer *buffer,
18162306a36Sopenharmony_ci				  binder_size_t buffer_offset,
18262306a36Sopenharmony_ci				  size_t bytes);
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#endif /* _LINUX_BINDER_ALLOC_H */
18562306a36Sopenharmony_ci
186