ANDROID: binder: fix KMI-break due to proc->dmap

Add 'struct binder_proc_wrap' to support the addition of new members in
'struct binder_proc' without breaking the KMI. In this case, proc->dmap
was backported from upstream and needs to be migrated into this wrapper.

Avoids the following KMI issue:

  function symbol 'int __traceiter_binder_transaction_received(void*, struct binder_transaction*)' changed
    CRC changed from 0x74e9c98b to 0x7af6cf5a

  type 'struct binder_proc' changed
    byte size changed from 584 to 600
    member 'struct dbitmap dmap' was added
    16 members ('struct list_head todo' .. 'u64 android_oem_data1') changed
      offset changed by 128

Bug: 298520209
Change-Id: Icbbee14a8f16d0881faf8d5673582e785f98e8cf
Signed-off-by: Carlos Llamas <cmllamas@google.com>
(cherry picked from commit af55892f201c8f709725d75d306b1cdd20984b97)
[cmllamas: merge binder_proc_wrap_entry() with new proc_wrapper()]
Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
Carlos Llamas
2024-07-25 18:13:35 +00:00
parent a55053f3a8
commit f8f9a197f4
2 changed files with 23 additions and 19 deletions

View File

@@ -1265,7 +1265,7 @@ static int get_ref_desc_olocked(struct binder_proc *proc,
struct binder_node *node,
u32 *desc)
{
struct dbitmap *dmap = &proc->dmap;
struct dbitmap *dmap = &proc_wrapper(proc)->dmap;
unsigned int nbits, offset;
unsigned long *new, bit;
@@ -1381,7 +1381,7 @@ retry:
static void binder_cleanup_ref_olocked(struct binder_ref *ref)
{
struct dbitmap *dmap = &ref->proc->dmap;
struct dbitmap *dmap = &proc_wrapper(ref->proc)->dmap;
bool delete_node = false;
binder_debug(BINDER_DEBUG_INTERNAL_REFS,
@@ -1556,11 +1556,12 @@ static void binder_free_ref(struct binder_ref *ref)
/* shrink descriptor bitmap if needed */
static void try_shrink_dmap(struct binder_proc *proc)
{
struct dbitmap *dmap = &proc_wrapper(proc)->dmap;
unsigned long *new;
int nbits;
binder_proc_lock(proc);
nbits = dbitmap_shrink_nbits(&proc->dmap);
nbits = dbitmap_shrink_nbits(dmap);
binder_proc_unlock(proc);
if (!nbits)
@@ -1568,7 +1569,7 @@ static void try_shrink_dmap(struct binder_proc *proc)
new = bitmap_zalloc(nbits, GFP_KERNEL);
binder_proc_lock(proc);
dbitmap_shrink(&proc->dmap, new, nbits);
dbitmap_shrink(dmap, new, nbits);
binder_proc_unlock(proc);
}
@@ -5245,7 +5246,6 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc)
static void binder_free_proc(struct binder_proc *proc)
{
struct binder_proc_wrap *proc_wrap;
struct binder_device *device;
BUG_ON(!list_empty(&proc->todo));
@@ -5262,10 +5262,9 @@ static void binder_free_proc(struct binder_proc *proc)
put_task_struct(proc->tsk);
put_cred(proc->cred);
binder_stats_deleted(BINDER_STAT_PROC);
dbitmap_free(&proc->dmap);
dbitmap_free(&proc_wrapper(proc)->dmap);
trace_android_vh_binder_free_proc(proc);
proc_wrap = binder_proc_wrap_entry(proc);
kfree(proc_wrap);
kfree(proc_wrapper(proc));
}
static void binder_free_thread(struct binder_thread *thread)
@@ -5986,7 +5985,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
return -ENOMEM;
proc = &proc_wrap->proc;
dbitmap_init(&proc->dmap);
dbitmap_init(&proc_wrapper(proc)->dmap);
spin_lock_init(&proc->inner_lock);
spin_lock_init(&proc->outer_lock);
get_task_struct(current->group_leader);

View File

@@ -395,8 +395,6 @@ enum binder_prio_state {
* @freeze_wait: waitqueue of processes waiting for all outstanding
* transactions to be processed
* (protected by @inner_lock)
* @dmap dbitmap to manage available reference descriptors
* (protected by @outer_lock)
* @todo: list of work for this process
* (protected by @inner_lock)
* @stats: per-process binder statistics
@@ -446,7 +444,6 @@ struct binder_proc {
bool sync_recv;
bool async_recv;
wait_queue_head_t freeze_wait;
struct dbitmap dmap;
struct list_head todo;
struct binder_stats stats;
struct list_head delivered_death;
@@ -464,27 +461,35 @@ struct binder_proc {
bool oneway_spam_detection_enabled;
};
/**
* struct binder_proc_wrap - wrapper to preserve KMI in binder_proc
* @proc: binder_proc being wrapped
* @dmap: dbitmap to manage available reference descriptors
* (protected by @proc.outer_lock)
* @lock: protects @proc->alloc fields
*/
struct binder_proc_wrap {
struct binder_proc proc;
struct dbitmap dmap;
spinlock_t lock;
};
static inline
struct binder_proc_wrap *proc_wrapper(struct binder_proc *proc)
{
return container_of(proc, struct binder_proc_wrap, proc);
}
static inline struct binder_proc *
binder_proc_entry(struct binder_alloc *alloc)
{
return container_of(alloc, struct binder_proc, alloc);
}
static inline struct binder_proc_wrap *
binder_proc_wrap_entry(struct binder_proc *proc)
{
return container_of(proc, struct binder_proc_wrap, proc);
}
static inline struct binder_proc_wrap *
binder_alloc_to_proc_wrap(struct binder_alloc *alloc)
{
return binder_proc_wrap_entry(binder_proc_entry(alloc));
return proc_wrapper(binder_proc_entry(alloc));
}
static inline void binder_alloc_lock_init(struct binder_alloc *alloc)