mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: - a bit more MM - procfs updates - dynamic-debug fixes - lib/ updates - checkpatch - epoll - nilfs2 - signals - rapidio - PID management cleanup and optimization - kcov updates - sysvipc updates - quite a few misc things all over the place * emailed patches from Andrew Morton <[email protected]>: (94 commits) EXPERT Kconfig menu: fix broken EXPERT menu include/asm-generic/topology.h: remove unused parent_node() macro arch/tile/include/asm/topology.h: remove unused parent_node() macro arch/sparc/include/asm/topology_64.h: remove unused parent_node() macro arch/sh/include/asm/topology.h: remove unused parent_node() macro arch/ia64/include/asm/topology.h: remove unused parent_node() macro drivers/pcmcia/sa1111_badge4.c: avoid unused function warning mm: add infrastructure for get_user_pages_fast() benchmarking sysvipc: make get_maxid O(1) again sysvipc: properly name ipc_addid() limit parameter sysvipc: duplicate lock comments wrt ipc_addid() sysvipc: unteach ids->next_id for !CHECKPOINT_RESTORE initramfs: use time64_t timestamps drivers/watchdog: make use of devm_register_reboot_notifier() kernel/reboot.c: add devm_register_reboot_notifier() kcov: update documentation Makefile: support flag -fsanitizer-coverage=trace-cmp kcov: support comparison operands collection kcov: remove pointless current != NULL check kernel/panic.c: add TAINT_AUX ...
This commit is contained in:
commit
fa7f578076
115 changed files with 1892 additions and 952 deletions
|
|
@ -515,6 +515,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
|
|||
sma->sem_nsems = nsems;
|
||||
sma->sem_ctime = ktime_get_real_seconds();
|
||||
|
||||
/* ipc_addid() locks sma upon success. */
|
||||
retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
|
||||
if (retval < 0) {
|
||||
call_rcu(&sma->sem_perm.rcu, sem_rcu_free);
|
||||
|
|
|
|||
|
|
@ -601,6 +601,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
|
|||
shp->shm_file = file;
|
||||
shp->shm_creator = current;
|
||||
|
||||
/* ipc_addid() locks shp upon success. */
|
||||
error = ipc_addid(&shm_ids(ns), &shp->shm_perm, ns->shm_ctlmni);
|
||||
if (error < 0)
|
||||
goto no_id;
|
||||
|
|
|
|||
101
ipc/util.c
101
ipc/util.c
|
|
@ -116,13 +116,16 @@ int ipc_init_ids(struct ipc_ids *ids)
|
|||
int err;
|
||||
ids->in_use = 0;
|
||||
ids->seq = 0;
|
||||
ids->next_id = -1;
|
||||
init_rwsem(&ids->rwsem);
|
||||
err = rhashtable_init(&ids->key_ht, &ipc_kht_params);
|
||||
if (err)
|
||||
return err;
|
||||
idr_init(&ids->ipcs_idr);
|
||||
ids->tables_initialized = true;
|
||||
ids->max_id = -1;
|
||||
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||
ids->next_id = -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -186,41 +189,51 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipc_get_maxid - get the last assigned id
|
||||
* @ids: ipc identifier set
|
||||
*
|
||||
* Called with ipc_ids.rwsem held.
|
||||
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||
/*
|
||||
* Specify desired id for next allocated IPC object.
|
||||
*/
|
||||
int ipc_get_maxid(struct ipc_ids *ids)
|
||||
#define ipc_idr_alloc(ids, new) \
|
||||
idr_alloc(&(ids)->ipcs_idr, (new), \
|
||||
(ids)->next_id < 0 ? 0 : ipcid_to_idx((ids)->next_id),\
|
||||
0, GFP_NOWAIT)
|
||||
|
||||
static inline int ipc_buildid(int id, struct ipc_ids *ids,
|
||||
struct kern_ipc_perm *new)
|
||||
{
|
||||
struct kern_ipc_perm *ipc;
|
||||
int max_id = -1;
|
||||
int total, id;
|
||||
|
||||
if (ids->in_use == 0)
|
||||
return -1;
|
||||
|
||||
if (ids->in_use == IPCMNI)
|
||||
return IPCMNI - 1;
|
||||
|
||||
/* Look for the last assigned id */
|
||||
total = 0;
|
||||
for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
|
||||
ipc = idr_find(&ids->ipcs_idr, id);
|
||||
if (ipc != NULL) {
|
||||
max_id = id;
|
||||
total++;
|
||||
}
|
||||
if (ids->next_id < 0) { /* default, behave as !CHECKPOINT_RESTORE */
|
||||
new->seq = ids->seq++;
|
||||
if (ids->seq > IPCID_SEQ_MAX)
|
||||
ids->seq = 0;
|
||||
} else {
|
||||
new->seq = ipcid_to_seqx(ids->next_id);
|
||||
ids->next_id = -1;
|
||||
}
|
||||
return max_id;
|
||||
|
||||
return SEQ_MULTIPLIER * new->seq + id;
|
||||
}
|
||||
|
||||
#else
|
||||
#define ipc_idr_alloc(ids, new) \
|
||||
idr_alloc(&(ids)->ipcs_idr, (new), 0, 0, GFP_NOWAIT)
|
||||
|
||||
static inline int ipc_buildid(int id, struct ipc_ids *ids,
|
||||
struct kern_ipc_perm *new)
|
||||
{
|
||||
new->seq = ids->seq++;
|
||||
if (ids->seq > IPCID_SEQ_MAX)
|
||||
ids->seq = 0;
|
||||
|
||||
return SEQ_MULTIPLIER * new->seq + id;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CHECKPOINT_RESTORE */
|
||||
|
||||
/**
|
||||
* ipc_addid - add an ipc identifier
|
||||
* @ids: ipc identifier set
|
||||
* @new: new ipc permission set
|
||||
* @size: limit for the number of used ids
|
||||
* @limit: limit for the number of used ids
|
||||
*
|
||||
* Add an entry 'new' to the ipc ids idr. The permissions object is
|
||||
* initialised and the first free entry is set up and the id assigned
|
||||
|
|
@ -229,17 +242,16 @@ int ipc_get_maxid(struct ipc_ids *ids)
|
|||
*
|
||||
* Called with writer ipc_ids.rwsem held.
|
||||
*/
|
||||
int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
|
||||
int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int limit)
|
||||
{
|
||||
kuid_t euid;
|
||||
kgid_t egid;
|
||||
int id, err;
|
||||
int next_id = ids->next_id;
|
||||
|
||||
if (size > IPCMNI)
|
||||
size = IPCMNI;
|
||||
if (limit > IPCMNI)
|
||||
limit = IPCMNI;
|
||||
|
||||
if (!ids->tables_initialized || ids->in_use >= size)
|
||||
if (!ids->tables_initialized || ids->in_use >= limit)
|
||||
return -ENOSPC;
|
||||
|
||||
idr_preload(GFP_KERNEL);
|
||||
|
|
@ -254,9 +266,7 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
|
|||
new->cuid = new->uid = euid;
|
||||
new->gid = new->cgid = egid;
|
||||
|
||||
id = idr_alloc(&ids->ipcs_idr, new,
|
||||
(next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
|
||||
GFP_NOWAIT);
|
||||
id = ipc_idr_alloc(ids, new);
|
||||
idr_preload_end();
|
||||
|
||||
if (id >= 0 && new->key != IPC_PRIVATE) {
|
||||
|
|
@ -274,17 +284,11 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
|
|||
}
|
||||
|
||||
ids->in_use++;
|
||||
if (id > ids->max_id)
|
||||
ids->max_id = id;
|
||||
|
||||
if (next_id < 0) {
|
||||
new->seq = ids->seq++;
|
||||
if (ids->seq > IPCID_SEQ_MAX)
|
||||
ids->seq = 0;
|
||||
} else {
|
||||
new->seq = ipcid_to_seqx(next_id);
|
||||
ids->next_id = -1;
|
||||
}
|
||||
new->id = ipc_buildid(id, ids, new);
|
||||
|
||||
new->id = ipc_buildid(id, new->seq);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -429,6 +433,15 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
|
|||
ipc_kht_remove(ids, ipcp);
|
||||
ids->in_use--;
|
||||
ipcp->deleted = true;
|
||||
|
||||
if (unlikely(lid == ids->max_id)) {
|
||||
do {
|
||||
lid--;
|
||||
if (lid == -1)
|
||||
break;
|
||||
} while (!idr_find(&ids->ipcs_idr, lid));
|
||||
ids->max_id = lid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
26
ipc/util.h
26
ipc/util.h
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/ipc_namespace.h>
|
||||
|
||||
#define SEQ_MULTIPLIER (IPCMNI)
|
||||
|
||||
|
|
@ -99,9 +100,6 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
|||
/* must be called with ids->rwsem acquired for writing */
|
||||
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
|
||||
|
||||
/* must be called with ids->rwsem acquired for reading */
|
||||
int ipc_get_maxid(struct ipc_ids *);
|
||||
|
||||
/* must be called with both locks acquired. */
|
||||
void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
|
||||
|
||||
|
|
@ -111,6 +109,23 @@ void ipc_set_key_private(struct ipc_ids *, struct kern_ipc_perm *);
|
|||
/* must be called with ipcp locked */
|
||||
int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flg);
|
||||
|
||||
/**
|
||||
* ipc_get_maxid - get the last assigned id
|
||||
* @ids: ipc identifier set
|
||||
*
|
||||
* Called with ipc_ids.rwsem held for reading.
|
||||
*/
|
||||
static inline int ipc_get_maxid(struct ipc_ids *ids)
|
||||
{
|
||||
if (ids->in_use == 0)
|
||||
return -1;
|
||||
|
||||
if (ids->in_use == IPCMNI)
|
||||
return IPCMNI - 1;
|
||||
|
||||
return ids->max_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* For allocation that need to be freed by RCU.
|
||||
* Objects are reference counted, they start with reference count 1.
|
||||
|
|
@ -146,11 +161,6 @@ extern struct msg_msg *load_msg(const void __user *src, size_t len);
|
|||
extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst);
|
||||
extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len);
|
||||
|
||||
static inline int ipc_buildid(int id, int seq)
|
||||
{
|
||||
return SEQ_MULTIPLIER * seq + id;
|
||||
}
|
||||
|
||||
static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
|
||||
{
|
||||
return uid / SEQ_MULTIPLIER != ipcp->seq;
|
||||
|
|
|
|||
Loading…
Reference in a new issue