shmget: add "shmflg" checks for SHM_HUGE*
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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() */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user