1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2a5494dcdSEric W. Biederman /*
3a5494dcdSEric W. Biederman * Copyright (C) 2007
4a5494dcdSEric W. Biederman *
5a5494dcdSEric W. Biederman * Author: Eric Biederman <ebiederm@xmision.com>
6a5494dcdSEric W. Biederman */
7a5494dcdSEric W. Biederman
8a5494dcdSEric W. Biederman #include <linux/module.h>
9a5494dcdSEric W. Biederman #include <linux/ipc.h>
10a5494dcdSEric W. Biederman #include <linux/nsproxy.h>
11a5494dcdSEric W. Biederman #include <linux/sysctl.h>
12a5494dcdSEric W. Biederman #include <linux/uaccess.h>
135563cabdSMichal Clapinski #include <linux/capability.h>
14ae5e1b22SPavel Emelyanov #include <linux/ipc_namespace.h>
156546bc42SNadia Derbey #include <linux/msg.h>
161f5c135eSAlexey Gladkov #include <linux/slab.h>
178d5b1a9fSAlexey Gladkov #include <linux/cred.h>
186546bc42SNadia Derbey #include "util.h"
19a5494dcdSEric W. Biederman
proc_ipc_dointvec_minmax_orphans(struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos)20a5c5928bSJoe Perches static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write,
2132927393SChristoph Hellwig void *buffer, size_t *lenp, loff_t *ppos)
22b34a6b1dSVasiliy Kulikov {
23dd141a49SAlexey Gladkov struct ipc_namespace *ns =
24dd141a49SAlexey Gladkov container_of(table->data, struct ipc_namespace, shm_rmid_forced);
251f5c135eSAlexey Gladkov int err;
261f5c135eSAlexey Gladkov
27dd141a49SAlexey Gladkov err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
28b34a6b1dSVasiliy Kulikov
29b34a6b1dSVasiliy Kulikov if (err < 0)
30b34a6b1dSVasiliy Kulikov return err;
31b34a6b1dSVasiliy Kulikov if (ns->shm_rmid_forced)
32b34a6b1dSVasiliy Kulikov shm_destroy_orphaned(ns);
33b34a6b1dSVasiliy Kulikov return err;
34b34a6b1dSVasiliy Kulikov }
35b34a6b1dSVasiliy Kulikov
proc_ipc_auto_msgmni(struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos)360050ee05SManfred Spraul static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,
3732927393SChristoph Hellwig void *buffer, size_t *lenp, loff_t *ppos)
389eefe520SNadia Derbey {
399eefe520SNadia Derbey struct ctl_table ipc_table;
400050ee05SManfred Spraul int dummy = 0;
419eefe520SNadia Derbey
429eefe520SNadia Derbey memcpy(&ipc_table, table, sizeof(ipc_table));
430050ee05SManfred Spraul ipc_table.data = &dummy;
449eefe520SNadia Derbey
450050ee05SManfred Spraul if (write)
460050ee05SManfred Spraul pr_info_once("writing to auto_msgmni has no effect");
479eefe520SNadia Derbey
480050ee05SManfred Spraul return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
499eefe520SNadia Derbey }
509eefe520SNadia Derbey
proc_ipc_sem_dointvec(struct ctl_table * table,int write,void * buffer,size_t * lenp,loff_t * ppos)518c81ddd2SWaiman Long static int proc_ipc_sem_dointvec(struct ctl_table *table, int write,
52fff1662cSTobias Klauser void *buffer, size_t *lenp, loff_t *ppos)
538c81ddd2SWaiman Long {
54dd141a49SAlexey Gladkov struct ipc_namespace *ns =
55dd141a49SAlexey Gladkov container_of(table->data, struct ipc_namespace, sem_ctls);
568c81ddd2SWaiman Long int ret, semmni;
571f5c135eSAlexey Gladkov
588c81ddd2SWaiman Long semmni = ns->sem_ctls[3];
591f5c135eSAlexey Gladkov ret = proc_dointvec(table, write, buffer, lenp, ppos);
608c81ddd2SWaiman Long
618c81ddd2SWaiman Long if (!ret)
62def7343fSAlexey Gladkov ret = sem_check_semmni(ns);
638c81ddd2SWaiman Long
648c81ddd2SWaiman Long /*
658c81ddd2SWaiman Long * Reset the semmni value if an error happens.
668c81ddd2SWaiman Long */
678c81ddd2SWaiman Long if (ret)
688c81ddd2SWaiman Long ns->sem_ctls[3] = semmni;
698c81ddd2SWaiman Long return ret;
708c81ddd2SWaiman Long }
718c81ddd2SWaiman Long
725ac893b8SWaiman Long int ipc_mni = IPCMNI;
735ac893b8SWaiman Long int ipc_mni_shift = IPCMNI_SHIFT;
7499db46eaSManfred Spraul int ipc_min_cycle = RADIX_TREE_MAP_SIZE;
759eefe520SNadia Derbey
761f5c135eSAlexey Gladkov static struct ctl_table ipc_sysctls[] = {
77a5494dcdSEric W. Biederman {
78a5494dcdSEric W. Biederman .procname = "shmmax",
79a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlmax,
80a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlmax),
81a5494dcdSEric W. Biederman .mode = 0644,
821f5c135eSAlexey Gladkov .proc_handler = proc_doulongvec_minmax,
83a5494dcdSEric W. Biederman },
84a5494dcdSEric W. Biederman {
85a5494dcdSEric W. Biederman .procname = "shmall",
86a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlall,
87a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlall),
88a5494dcdSEric W. Biederman .mode = 0644,
891f5c135eSAlexey Gladkov .proc_handler = proc_doulongvec_minmax,
90a5494dcdSEric W. Biederman },
91a5494dcdSEric W. Biederman {
92a5494dcdSEric W. Biederman .procname = "shmmni",
93a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlmni,
94a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlmni),
95a5494dcdSEric W. Biederman .mode = 0644,
961f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
97eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO,
986730e658SWaiman Long .extra2 = &ipc_mni,
99a5494dcdSEric W. Biederman },
100a5494dcdSEric W. Biederman {
101b34a6b1dSVasiliy Kulikov .procname = "shm_rmid_forced",
102b34a6b1dSVasiliy Kulikov .data = &init_ipc_ns.shm_rmid_forced,
103b34a6b1dSVasiliy Kulikov .maxlen = sizeof(init_ipc_ns.shm_rmid_forced),
104b34a6b1dSVasiliy Kulikov .mode = 0644,
105b34a6b1dSVasiliy Kulikov .proc_handler = proc_ipc_dointvec_minmax_orphans,
106dd141a49SAlexey Gladkov .extra1 = SYSCTL_ZERO,
107dd141a49SAlexey Gladkov .extra2 = SYSCTL_ONE,
108b34a6b1dSVasiliy Kulikov },
109b34a6b1dSVasiliy Kulikov {
110a5494dcdSEric W. Biederman .procname = "msgmax",
111a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmax,
112a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmax),
113a5494dcdSEric W. Biederman .mode = 0644,
1141f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
115eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO,
116eec4844fSMatteo Croce .extra2 = SYSCTL_INT_MAX,
117a5494dcdSEric W. Biederman },
118a5494dcdSEric W. Biederman {
119a5494dcdSEric W. Biederman .procname = "msgmni",
120a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmni,
121a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmni),
122a5494dcdSEric W. Biederman .mode = 0644,
1231f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
124eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO,
1256730e658SWaiman Long .extra2 = &ipc_mni,
126a5494dcdSEric W. Biederman },
127a5494dcdSEric W. Biederman {
1280050ee05SManfred Spraul .procname = "auto_msgmni",
1290050ee05SManfred Spraul .data = NULL,
1300050ee05SManfred Spraul .maxlen = sizeof(int),
1310050ee05SManfred Spraul .mode = 0644,
1320050ee05SManfred Spraul .proc_handler = proc_ipc_auto_msgmni,
133eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO,
134eec4844fSMatteo Croce .extra2 = SYSCTL_ONE,
1350050ee05SManfred Spraul },
1360050ee05SManfred Spraul {
137a5494dcdSEric W. Biederman .procname = "msgmnb",
138a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmnb,
139a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmnb),
140a5494dcdSEric W. Biederman .mode = 0644,
1411f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
142eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO,
143eec4844fSMatteo Croce .extra2 = SYSCTL_INT_MAX,
144a5494dcdSEric W. Biederman },
145a5494dcdSEric W. Biederman {
146a5494dcdSEric W. Biederman .procname = "sem",
147a5494dcdSEric W. Biederman .data = &init_ipc_ns.sem_ctls,
148a5494dcdSEric W. Biederman .maxlen = 4*sizeof(int),
149a5494dcdSEric W. Biederman .mode = 0644,
1508c81ddd2SWaiman Long .proc_handler = proc_ipc_sem_dointvec,
151a5494dcdSEric W. Biederman },
15203f59566SStanislav Kinsbursky #ifdef CONFIG_CHECKPOINT_RESTORE
15303f59566SStanislav Kinsbursky {
15403f59566SStanislav Kinsbursky .procname = "sem_next_id",
15503f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_SEM_IDS].next_id,
15603f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id),
1570889f44eSAlexey Gladkov .mode = 0444,
1580889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
1590889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO,
1600889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX,
16103f59566SStanislav Kinsbursky },
16203f59566SStanislav Kinsbursky {
16303f59566SStanislav Kinsbursky .procname = "msg_next_id",
16403f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_MSG_IDS].next_id,
16503f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id),
1660889f44eSAlexey Gladkov .mode = 0444,
1670889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
1680889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO,
1690889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX,
17003f59566SStanislav Kinsbursky },
17103f59566SStanislav Kinsbursky {
17203f59566SStanislav Kinsbursky .procname = "shm_next_id",
17303f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_SHM_IDS].next_id,
17403f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id),
1750889f44eSAlexey Gladkov .mode = 0444,
1760889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax,
1770889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO,
1780889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX,
17903f59566SStanislav Kinsbursky },
18003f59566SStanislav Kinsbursky #endif
181a5494dcdSEric W. Biederman {}
182a5494dcdSEric W. Biederman };
183a5494dcdSEric W. Biederman
set_lookup(struct ctl_table_root * root)1841f5c135eSAlexey Gladkov static struct ctl_table_set *set_lookup(struct ctl_table_root *root)
185a5494dcdSEric W. Biederman {
1861f5c135eSAlexey Gladkov return ¤t->nsproxy->ipc_ns->ipc_set;
1871f5c135eSAlexey Gladkov }
1881f5c135eSAlexey Gladkov
set_is_seen(struct ctl_table_set * set)1891f5c135eSAlexey Gladkov static int set_is_seen(struct ctl_table_set *set)
1901f5c135eSAlexey Gladkov {
1911f5c135eSAlexey Gladkov return ¤t->nsproxy->ipc_ns->ipc_set == set;
1921f5c135eSAlexey Gladkov }
1931f5c135eSAlexey Gladkov
ipc_set_ownership(struct ctl_table_header * head,kuid_t * uid,kgid_t * gid)1948d5b1a9fSAlexey Gladkov static void ipc_set_ownership(struct ctl_table_header *head,
1958d5b1a9fSAlexey Gladkov kuid_t *uid, kgid_t *gid)
1968d5b1a9fSAlexey Gladkov {
1978d5b1a9fSAlexey Gladkov struct ipc_namespace *ns =
1988d5b1a9fSAlexey Gladkov container_of(head->set, struct ipc_namespace, ipc_set);
1998d5b1a9fSAlexey Gladkov
2008d5b1a9fSAlexey Gladkov kuid_t ns_root_uid = make_kuid(ns->user_ns, 0);
2018d5b1a9fSAlexey Gladkov kgid_t ns_root_gid = make_kgid(ns->user_ns, 0);
2028d5b1a9fSAlexey Gladkov
2038d5b1a9fSAlexey Gladkov *uid = uid_valid(ns_root_uid) ? ns_root_uid : GLOBAL_ROOT_UID;
2048d5b1a9fSAlexey Gladkov *gid = gid_valid(ns_root_gid) ? ns_root_gid : GLOBAL_ROOT_GID;
2058d5b1a9fSAlexey Gladkov }
2068d5b1a9fSAlexey Gladkov
ipc_permissions(struct ctl_table_header * head,struct ctl_table * table)2070889f44eSAlexey Gladkov static int ipc_permissions(struct ctl_table_header *head, struct ctl_table *table)
2080889f44eSAlexey Gladkov {
2090889f44eSAlexey Gladkov int mode = table->mode;
2100889f44eSAlexey Gladkov
2110889f44eSAlexey Gladkov #ifdef CONFIG_CHECKPOINT_RESTORE
2128d5b1a9fSAlexey Gladkov struct ipc_namespace *ns =
2138d5b1a9fSAlexey Gladkov container_of(head->set, struct ipc_namespace, ipc_set);
2140889f44eSAlexey Gladkov
2150889f44eSAlexey Gladkov if (((table->data == &ns->ids[IPC_SEM_IDS].next_id) ||
2160889f44eSAlexey Gladkov (table->data == &ns->ids[IPC_MSG_IDS].next_id) ||
2170889f44eSAlexey Gladkov (table->data == &ns->ids[IPC_SHM_IDS].next_id)) &&
2180889f44eSAlexey Gladkov checkpoint_restore_ns_capable(ns->user_ns))
2190889f44eSAlexey Gladkov mode = 0666;
2208d5b1a9fSAlexey Gladkov else
2210889f44eSAlexey Gladkov #endif
2228d5b1a9fSAlexey Gladkov {
2238d5b1a9fSAlexey Gladkov kuid_t ns_root_uid;
2248d5b1a9fSAlexey Gladkov kgid_t ns_root_gid;
2258d5b1a9fSAlexey Gladkov
226*96f1d909SThomas Weißschuh ipc_set_ownership(head, &ns_root_uid, &ns_root_gid);
2278d5b1a9fSAlexey Gladkov
2288d5b1a9fSAlexey Gladkov if (uid_eq(current_euid(), ns_root_uid))
2298d5b1a9fSAlexey Gladkov mode >>= 6;
2308d5b1a9fSAlexey Gladkov
2318d5b1a9fSAlexey Gladkov else if (in_egroup_p(ns_root_gid))
2328d5b1a9fSAlexey Gladkov mode >>= 3;
2338d5b1a9fSAlexey Gladkov }
2348d5b1a9fSAlexey Gladkov
2358d5b1a9fSAlexey Gladkov mode &= 7;
2368d5b1a9fSAlexey Gladkov
2378d5b1a9fSAlexey Gladkov return (mode << 6) | (mode << 3) | mode;
2380889f44eSAlexey Gladkov }
2390889f44eSAlexey Gladkov
2401f5c135eSAlexey Gladkov static struct ctl_table_root set_root = {
2411f5c135eSAlexey Gladkov .lookup = set_lookup,
2420889f44eSAlexey Gladkov .permissions = ipc_permissions,
2438d5b1a9fSAlexey Gladkov .set_ownership = ipc_set_ownership,
244a5494dcdSEric W. Biederman };
245a5494dcdSEric W. Biederman
setup_ipc_sysctls(struct ipc_namespace * ns)2461f5c135eSAlexey Gladkov bool setup_ipc_sysctls(struct ipc_namespace *ns)
2471f5c135eSAlexey Gladkov {
2481f5c135eSAlexey Gladkov struct ctl_table *tbl;
2491f5c135eSAlexey Gladkov
2501f5c135eSAlexey Gladkov setup_sysctl_set(&ns->ipc_set, &set_root, set_is_seen);
2511f5c135eSAlexey Gladkov
2521f5c135eSAlexey Gladkov tbl = kmemdup(ipc_sysctls, sizeof(ipc_sysctls), GFP_KERNEL);
2531f5c135eSAlexey Gladkov if (tbl) {
2541f5c135eSAlexey Gladkov int i;
2551f5c135eSAlexey Gladkov
2561f5c135eSAlexey Gladkov for (i = 0; i < ARRAY_SIZE(ipc_sysctls); i++) {
25738cd5b12SAlexey Gladkov if (tbl[i].data == &init_ipc_ns.shm_ctlmax)
2581f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlmax;
2591f5c135eSAlexey Gladkov
26038cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_ctlall)
2611f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlall;
2621f5c135eSAlexey Gladkov
26338cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_ctlmni)
2641f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlmni;
2651f5c135eSAlexey Gladkov
26638cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_rmid_forced)
2671f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_rmid_forced;
2681f5c135eSAlexey Gladkov
26938cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmax)
2701f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmax;
2711f5c135eSAlexey Gladkov
27238cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmni)
2731f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmni;
2741f5c135eSAlexey Gladkov
27538cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmnb)
2761f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmnb;
2771f5c135eSAlexey Gladkov
27838cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.sem_ctls)
2791f5c135eSAlexey Gladkov tbl[i].data = &ns->sem_ctls;
2801f5c135eSAlexey Gladkov #ifdef CONFIG_CHECKPOINT_RESTORE
28138cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_SEM_IDS].next_id)
2821f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_SEM_IDS].next_id;
2831f5c135eSAlexey Gladkov
28438cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_MSG_IDS].next_id)
2851f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_MSG_IDS].next_id;
2861f5c135eSAlexey Gladkov
28738cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_SHM_IDS].next_id)
2881f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_SHM_IDS].next_id;
2891f5c135eSAlexey Gladkov #endif
29038cd5b12SAlexey Gladkov else
2911f5c135eSAlexey Gladkov tbl[i].data = NULL;
2921f5c135eSAlexey Gladkov }
2931f5c135eSAlexey Gladkov
294bff97cf1SJoel Granados ns->ipc_sysctls = __register_sysctl_table(&ns->ipc_set,
295bff97cf1SJoel Granados "kernel", tbl,
296bff97cf1SJoel Granados ARRAY_SIZE(ipc_sysctls));
2971f5c135eSAlexey Gladkov }
2981f5c135eSAlexey Gladkov if (!ns->ipc_sysctls) {
2991f5c135eSAlexey Gladkov kfree(tbl);
3001f5c135eSAlexey Gladkov retire_sysctl_set(&ns->ipc_set);
3011f5c135eSAlexey Gladkov return false;
3021f5c135eSAlexey Gladkov }
3031f5c135eSAlexey Gladkov
3041f5c135eSAlexey Gladkov return true;
3051f5c135eSAlexey Gladkov }
3061f5c135eSAlexey Gladkov
retire_ipc_sysctls(struct ipc_namespace * ns)3071f5c135eSAlexey Gladkov void retire_ipc_sysctls(struct ipc_namespace *ns)
3081f5c135eSAlexey Gladkov {
3091f5c135eSAlexey Gladkov struct ctl_table *tbl;
3101f5c135eSAlexey Gladkov
3111f5c135eSAlexey Gladkov tbl = ns->ipc_sysctls->ctl_table_arg;
3121f5c135eSAlexey Gladkov unregister_sysctl_table(ns->ipc_sysctls);
3131f5c135eSAlexey Gladkov retire_sysctl_set(&ns->ipc_set);
3141f5c135eSAlexey Gladkov kfree(tbl);
3151f5c135eSAlexey Gladkov }
3161f5c135eSAlexey Gladkov
ipc_sysctl_init(void)317a5494dcdSEric W. Biederman static int __init ipc_sysctl_init(void)
318a5494dcdSEric W. Biederman {
3191f5c135eSAlexey Gladkov if (!setup_ipc_sysctls(&init_ipc_ns)) {
3201f5c135eSAlexey Gladkov pr_warn("ipc sysctl registration failed\n");
3211f5c135eSAlexey Gladkov return -ENOMEM;
3221f5c135eSAlexey Gladkov }
323a5494dcdSEric W. Biederman return 0;
324a5494dcdSEric W. Biederman }
325a5494dcdSEric W. Biederman
3266d08a256SDavidlohr Bueso device_initcall(ipc_sysctl_init);
3275ac893b8SWaiman Long
ipc_mni_extend(char * str)3285ac893b8SWaiman Long static int __init ipc_mni_extend(char *str)
3295ac893b8SWaiman Long {
3305ac893b8SWaiman Long ipc_mni = IPCMNI_EXTEND;
3315ac893b8SWaiman Long ipc_mni_shift = IPCMNI_EXTEND_SHIFT;
33299db46eaSManfred Spraul ipc_min_cycle = IPCMNI_EXTEND_MIN_CYCLE;
3335ac893b8SWaiman Long pr_info("IPCMNI extended to %d.\n", ipc_mni);
3345ac893b8SWaiman Long return 0;
3355ac893b8SWaiman Long }
3365ac893b8SWaiman Long early_param("ipcmni_extend", ipc_mni_extend);
337