189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew/* 215756239e687146c5052c724352a1d16201d0927Li Wang * Copyright (c) International Business Machines Corp., 2001 315756239e687146c5052c724352a1d16201d0927Li Wang * Copyright (c) Linux Test Project, 2001-2017 489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 515756239e687146c5052c724352a1d16201d0927Li Wang * This program is free software; you can redistribute it and/or modify 615756239e687146c5052c724352a1d16201d0927Li Wang * it under the terms of the GNU General Public License as published by 715756239e687146c5052c724352a1d16201d0927Li Wang * the Free Software Foundation; either version 2 of the License, or 815756239e687146c5052c724352a1d16201d0927Li Wang * (at your option) any later version. 989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 1015756239e687146c5052c724352a1d16201d0927Li Wang * This program is distributed in the hope that it will be useful, 1115756239e687146c5052c724352a1d16201d0927Li Wang * but WITHOUT ANY WARRANTY; without even the implied warranty of 1215756239e687146c5052c724352a1d16201d0927Li Wang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 1315756239e687146c5052c724352a1d16201d0927Li Wang * the GNU General Public License for more details. 1489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 1589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 1689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew/* 1789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * DESCRIPTION 1889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * hugeshmat01 - test that shmat() works correctly 1989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 2089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * ALGORITHM 2189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * create a large shared memory resouce with read/write permissions 2289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * loop if that option was specified 2389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * call shmat() with the TEST() macro using three valid conditions 2489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * check the return code 2589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * if failure, issue a FAIL message. 2689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * otherwise, 2789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * if doing functionality testing 2889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * check for the correct conditions after the call 291cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang * if correct, 3089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * issue a PASS message 3189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * otherwise 3289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * issue a FAIL message 3389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * call cleanup 3489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 3589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * HISTORY 3689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 03/2001 - Written by Wayne Boyer 3789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * 04/2004 - Updated by Robbie Williamson 3889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 3989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 40a14f756d5890cee192f1cffe403b7607074a9b72Cyril Hrubis#include <limits.h> 41676746ed5fc3c897c2018c310d0fb72dabd18d8cLi Wang#include "hugetlb.h" 4289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 4315756239e687146c5052c724352a1d16201d0927Li Wang#define CASE0 10 /* values to write into the shared */ 4415756239e687146c5052c724352a1d16201d0927Li Wang#define CASE1 20 /* memory location. */ 4589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 461cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhangstatic size_t shm_size; 47354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic int shm_id_1 = -1; 48354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void *addr; 4989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 50491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhangstatic long hugepages = 128; 5115756239e687146c5052c724352a1d16201d0927Li Wang 5215756239e687146c5052c724352a1d16201d0927Li Wangstatic struct tst_option options[] = { 5315756239e687146c5052c724352a1d16201d0927Li Wang {"s:", &nr_opt, "-s num Set the number of the been allocated hugepages"}, 54354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao {NULL, NULL, NULL} 55491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang}; 56491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang 5715756239e687146c5052c724352a1d16201d0927Li Wangstatic struct tcase { 58354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int *shmid; 5989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew void *addr; 60354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao int flags; 6115756239e687146c5052c724352a1d16201d0927Li Wang} tcases[] = { 6289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* a straight forward read/write attach */ 6315756239e687146c5052c724352a1d16201d0927Li Wang {&shm_id_1, 0, 0}, 6415756239e687146c5052c724352a1d16201d0927Li Wang /* 6515756239e687146c5052c724352a1d16201d0927Li Wang * an attach using non aligned memory 6615756239e687146c5052c724352a1d16201d0927Li Wang * -1 will be replaced with an unaligned addr 6715756239e687146c5052c724352a1d16201d0927Li Wang */ 6815756239e687146c5052c724352a1d16201d0927Li Wang {&shm_id_1, (void *)-1, SHM_RND}, 6915756239e687146c5052c724352a1d16201d0927Li Wang /* a read only attach */ 7015756239e687146c5052c724352a1d16201d0927Li Wang {&shm_id_1, 0, SHM_RDONLY} 7189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew}; 7289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 7315756239e687146c5052c724352a1d16201d0927Li Wangstatic void check_functionality(unsigned int i); 741cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang 7515756239e687146c5052c724352a1d16201d0927Li Wangstatic void verify_hugeshmat(unsigned int i) 7689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew{ 7715756239e687146c5052c724352a1d16201d0927Li Wang struct tcase *tc = &tcases[i]; 7815756239e687146c5052c724352a1d16201d0927Li Wang 7915756239e687146c5052c724352a1d16201d0927Li Wang addr = shmat(*(tc->shmid), tc->addr, tc->flags); 8015756239e687146c5052c724352a1d16201d0927Li Wang if (addr == (void *)-1) { 8115756239e687146c5052c724352a1d16201d0927Li Wang tst_brk(TFAIL | TERRNO, "shmat"); 8215756239e687146c5052c724352a1d16201d0927Li Wang } else { 8315756239e687146c5052c724352a1d16201d0927Li Wang check_functionality(i); 8489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 8515756239e687146c5052c724352a1d16201d0927Li Wang 8615756239e687146c5052c724352a1d16201d0927Li Wang /* 8715756239e687146c5052c724352a1d16201d0927Li Wang * addr in tcases[0] will be used to generate an unaligned 8815756239e687146c5052c724352a1d16201d0927Li Wang * address for tcases[1] 8915756239e687146c5052c724352a1d16201d0927Li Wang */ 9015756239e687146c5052c724352a1d16201d0927Li Wang if (i == 0 && addr != (void *)-1) 9115756239e687146c5052c724352a1d16201d0927Li Wang tc[1].addr = (void *)(((unsigned long)addr & 9215756239e687146c5052c724352a1d16201d0927Li Wang ~(SHMLBA - 1)) + SHMLBA - 1); 9315756239e687146c5052c724352a1d16201d0927Li Wang if (shmdt(addr) == -1) 9415756239e687146c5052c724352a1d16201d0927Li Wang tst_brk(TBROK | TERRNO, "shmdt"); 9589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew} 9689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 9789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew/* 984bb656a129f7507823e9e6d6b98b1a02fd80ef89subrata_modak * check_functionality - check various conditions to make sure they 9989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * are correct. 10089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 10115756239e687146c5052c724352a1d16201d0927Li Wangstatic void check_functionality(unsigned int i) 10289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew{ 10389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew void *orig_add; 10489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew int *shared; 10589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew struct shmid_ds buf; 10689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 10789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew shared = (int *)addr; 10889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 10989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* stat the shared memory ID */ 1101cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang if (shmctl(shm_id_1, IPC_STAT, &buf) == -1) 11115756239e687146c5052c724352a1d16201d0927Li Wang tst_brk(TBROK | TERRNO, "shmctl"); 11289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 11389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* check the number of attaches */ 11489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew if (buf.shm_nattch != 1) { 11515756239e687146c5052c724352a1d16201d0927Li Wang tst_res(TFAIL, "# of attaches is incorrect"); 11689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew return; 11789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 11889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 11989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* check the size of the segment */ 1201cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang if (buf.shm_segsz != shm_size) { 12115756239e687146c5052c724352a1d16201d0927Li Wang tst_res(TFAIL, "segment size is incorrect"); 12289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew return; 12389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 12489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 12589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* check for specific conditions depending on the type of attach */ 1261cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang switch (i) { 12789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew case 0: 12889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* 12989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * Check the functionality of the first call by simply 13089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * "writing" a value to the shared memory space. 13189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * If this fails the program will get a SIGSEGV, dump 13289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * core and exit. 13389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 13489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew *shared = CASE0; 13589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew break; 13689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew case 1: 13789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* 13889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * Check the functionality of the second call by writing 13989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * a value to the shared memory space and then checking 14089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * that the original address given was rounded down as 14189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * specified in the man page. 14289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 14389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew *shared = CASE1; 14415756239e687146c5052c724352a1d16201d0927Li Wang orig_add = addr + ((unsigned long)tcases[i].addr % SHMLBA); 14515756239e687146c5052c724352a1d16201d0927Li Wang if (orig_add != tcases[i].addr) { 14615756239e687146c5052c724352a1d16201d0927Li Wang tst_res(TFAIL, "shared memory address is not " 147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao "correct"); 1481cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang return; 14989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 15089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew break; 15189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew case 2: 15289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew /* 15389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * This time the shared memory is read only. Read the value 15489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * and check that it is equal to the value set in case #2, 15589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew * because shared memory is persistent. 15689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew */ 15789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew if (*shared != CASE1) { 15815756239e687146c5052c724352a1d16201d0927Li Wang tst_res(TFAIL, "shared memory value isn't correct"); 1591cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang return; 16089e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 16189e9a4fe59b3e697750b2996d45b6a19156270f4robbiew break; 16289e9a4fe59b3e697750b2996d45b6a19156270f4robbiew } 16315756239e687146c5052c724352a1d16201d0927Li Wang tst_res(TPASS, "conditions and functionality are correct"); 16489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew} 16589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 16615756239e687146c5052c724352a1d16201d0927Li Wangstatic void setup(void) 16789e9a4fe59b3e697750b2996d45b6a19156270f4robbiew{ 168491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang long hpage_size; 169491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang 170a5489f1bc843b7bda74fca10fad2f8714b5fb090Li Wang save_nr_hugepages(); 17115756239e687146c5052c724352a1d16201d0927Li Wang if (nr_opt) 17215756239e687146c5052c724352a1d16201d0927Li Wang hugepages = SAFE_STRTOL(nr_opt, 0, LONG_MAX); 17389e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 174491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang set_sys_tune("nr_hugepages", hugepages, 1); 17515756239e687146c5052c724352a1d16201d0927Li Wang hpage_size = SAFE_READ_MEMINFO("Hugepagesize:") * 1024; 176491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang 177491f7280f3fa1b2d90ac0b46388fc447d6ffca9dCaspar Zhang shm_size = hpage_size * hugepages / 2; 178880e33d3c777066f9f56ac8db5ea49b6060f9d66Wanlong Gao update_shm_size(&shm_size); 17915756239e687146c5052c724352a1d16201d0927Li Wang shmkey = getipckey(); 1801cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang shm_id_1 = shmget(shmkey++, shm_size, 181354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao SHM_HUGETLB | SHM_RW | IPC_CREAT | IPC_EXCL); 1821cdba9b1ffe8592f544afcbd2abbd9be910f2988Caspar Zhang if (shm_id_1 == -1) 18315756239e687146c5052c724352a1d16201d0927Li Wang tst_brk(TBROK | TERRNO, "shmget"); 18489e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 18589e9a4fe59b3e697750b2996d45b6a19156270f4robbiew} 18689e9a4fe59b3e697750b2996d45b6a19156270f4robbiew 18715756239e687146c5052c724352a1d16201d0927Li Wangstatic void cleanup(void) 18889e9a4fe59b3e697750b2996d45b6a19156270f4robbiew{ 18989e9a4fe59b3e697750b2996d45b6a19156270f4robbiew rm_shm(shm_id_1); 190a5489f1bc843b7bda74fca10fad2f8714b5fb090Li Wang restore_nr_hugepages(); 19154a90b4ff7b63731c4cb3a876265e13a2363974dShang Yanfeng} 19215756239e687146c5052c724352a1d16201d0927Li Wang 19315756239e687146c5052c724352a1d16201d0927Li Wangstatic struct tst_test test = { 19415756239e687146c5052c724352a1d16201d0927Li Wang .needs_root = 1, 19515756239e687146c5052c724352a1d16201d0927Li Wang .needs_tmpdir = 1, 19615756239e687146c5052c724352a1d16201d0927Li Wang .options = options, 19715756239e687146c5052c724352a1d16201d0927Li Wang .tcnt = ARRAY_SIZE(tcases), 19815756239e687146c5052c724352a1d16201d0927Li Wang .test = verify_hugeshmat, 19915756239e687146c5052c724352a1d16201d0927Li Wang .setup = setup, 20015756239e687146c5052c724352a1d16201d0927Li Wang .cleanup = cleanup, 20115756239e687146c5052c724352a1d16201d0927Li Wang}; 202