shmget: add "shmflg" checks for SHM_HUGE*

This commit is contained in:
NAKAMURA Gou
2016-03-17 21:47:47 +09:00
parent d65135c040
commit 48167d3223
5 changed files with 39 additions and 5 deletions

View File

@ -13,6 +13,11 @@
#ifndef HEADER_ARCH_SHM_H
#define HEADER_ARCH_SHM_H
/* shmflg */
#define SHM_HUGE_SHIFT 26
#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
struct ipc_perm {
key_t key;
uid_t uid;

View File

@ -1332,13 +1332,33 @@ SYSCALL_DECLARE(shmget)
{
const key_t key = ihk_mc_syscall_arg0(ctx);
const size_t size = ihk_mc_syscall_arg1(ctx);
const int shmflg = ihk_mc_syscall_arg2(ctx);
const int shmflg0 = ihk_mc_syscall_arg2(ctx);
int shmid;
int error;
int shmflg = shmflg0;
dkprintf("shmget(%#lx,%#lx,%#x)\n", key, size, shmflg);
dkprintf("shmget(%#lx,%#lx,%#x)\n", key, size, shmflg0);
if (shmflg & SHM_HUGETLB) {
switch (shmflg & (0x3F << SHM_HUGE_SHIFT)) {
case 0:
shmflg |= SHM_HUGE_2MB; /* default hugepage size */
break;
case SHM_HUGE_2MB:
case SHM_HUGE_1GB:
break;
default:
error = -EINVAL;
goto out;
}
}
shmid = do_shmget(key, size, shmflg);
dkprintf("shmget(%#lx,%#lx,%#x): %d\n", key, size, shmflg, shmid);
return shmid;
error = 0;
out:
dkprintf("shmget(%#lx,%#lx,%#x): %d %d\n", key, size, shmflg0, error, shmid);
return (error)?: shmid;
} /* sys_shmget() */

View File

@ -25,6 +25,7 @@ enum {
IPC_CREAT = 01000,
IPC_EXCL = 02000,
SHM_HUGETLB = 04000,
SHM_RDONLY = 010000,
SHM_RND = 020000,
SHM_REMAP = 040000,
@ -49,7 +50,7 @@ enum {
struct shmobj {
struct memobj memobj; /* must be first */
int index;
uint8_t padding[4];
int pgshift;
size_t real_segsz;
struct shmid_ds ds;
struct list_head page_list;

View File

@ -136,6 +136,7 @@ int shmobj_create(struct shmid_ds *ds, struct memobj **objp)
obj->ds.shm_perm.seq = the_seq++;
obj->ds.shm_nattch = 1;
obj->index = -1;
obj->pgshift = PAGE_SHIFT;
obj->real_segsz = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
page_list_init(obj);
ihk_mc_spinlock_init(&obj->memobj.lock);

View File

@ -3536,6 +3536,7 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
int error;
struct shmid_ds ads;
struct shmobj *obj;
int pgshift;
dkprintf("do_shmget(%#lx,%#lx,%#x)\n", key, size, shmflg);
@ -3610,6 +3611,11 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
return -ENOSPC;
}
pgshift = PAGE_SHIFT;
if (shmflg & SHM_HUGETLB) {
pgshift = (shmflg >> SHM_HUGE_SHIFT) & 0x3F;
}
memset(&ads, 0, sizeof(ads));
ads.shm_perm.key = key;
ads.shm_perm.uid = proc->euid;
@ -3629,6 +3635,7 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
}
obj->index = ++the_maxi;
obj->pgshift = pgshift;
list_add(&obj->chain, &kds_list);
++the_shm_info.used_ids;