1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Xiao Yang <yangx.jy@cn.fujitsu.com> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci/* 7f08c3bdfSopenharmony_ci * Description: 8f08c3bdfSopenharmony_ci * If one memory is already locked by mlock2() with MLOCK_ONFAULT and then 9f08c3bdfSopenharmony_ci * it is locked again by mlock()(or mlock2() without MLOCK_ONFAULT), the 10f08c3bdfSopenharmony_ci * VmLck field in /proc/pid/status should increase once instead of twice. 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * This issue has been fixed in kernel: 13f08c3bdfSopenharmony_ci * 'b155b4fde5bd("mm: mlock: avoid increase mm->locked_vm on mlock() when already mlock2(,MLOCK_ONFAULT)")' 14f08c3bdfSopenharmony_ci */ 15f08c3bdfSopenharmony_ci#include <errno.h> 16f08c3bdfSopenharmony_ci#include <unistd.h> 17f08c3bdfSopenharmony_ci#include <sys/mman.h> 18f08c3bdfSopenharmony_ci#include <linux/mman.h> 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#include "tst_test.h" 21f08c3bdfSopenharmony_ci#include "lapi/syscalls.h" 22f08c3bdfSopenharmony_ci#include "lapi/mlock2.h" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistatic unsigned long pgsz; 25f08c3bdfSopenharmony_cistatic char *addr; 26f08c3bdfSopenharmony_ci 27f08c3bdfSopenharmony_cistatic void verify_mlock2(void) 28f08c3bdfSopenharmony_ci{ 29f08c3bdfSopenharmony_ci unsigned long bsize, asize1, asize2; 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci SAFE_FILE_LINES_SCANF("/proc/self/status", "VmLck: %lu", &bsize); 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_mlock2, addr, pgsz, MLOCK_ONFAULT)); 34f08c3bdfSopenharmony_ci if (TST_RET != 0) { 35f08c3bdfSopenharmony_ci if (TST_ERR == EINVAL) { 36f08c3bdfSopenharmony_ci tst_res(TCONF, 37f08c3bdfSopenharmony_ci "mlock2() didn't support MLOCK_ONFAULT"); 38f08c3bdfSopenharmony_ci } else { 39f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 40f08c3bdfSopenharmony_ci "mlock2(MLOCK_ONFAULT) failed"); 41f08c3bdfSopenharmony_ci } 42f08c3bdfSopenharmony_ci return; 43f08c3bdfSopenharmony_ci } 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_ci SAFE_FILE_LINES_SCANF("/proc/self/status", "VmLck: %lu", &asize1); 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ci if ((asize1 - bsize) * 1024 != pgsz) { 48f08c3bdfSopenharmony_ci tst_res(TFAIL, 49f08c3bdfSopenharmony_ci "mlock2(MLOCK_ONFAULT) locked %lu size, expected %lu", 50f08c3bdfSopenharmony_ci (asize1 - bsize) * 1024, pgsz); 51f08c3bdfSopenharmony_ci goto end; 52f08c3bdfSopenharmony_ci } 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_mlock2, addr, pgsz, 0)); 55f08c3bdfSopenharmony_ci if (TST_RET != 0) { 56f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "mlock2() failed"); 57f08c3bdfSopenharmony_ci goto end; 58f08c3bdfSopenharmony_ci } 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci SAFE_FILE_LINES_SCANF("/proc/self/status", "VmLck: %lu", &asize2); 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci if (asize1 != asize2) { 63f08c3bdfSopenharmony_ci tst_res(TFAIL, "Locking one memory again increased VmLck"); 64f08c3bdfSopenharmony_ci } else { 65f08c3bdfSopenharmony_ci tst_res(TPASS, 66f08c3bdfSopenharmony_ci "Locking one memory again didn't increased VmLck"); 67f08c3bdfSopenharmony_ci } 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ciend: 70f08c3bdfSopenharmony_ci SAFE_MUNLOCK(addr, pgsz); 71f08c3bdfSopenharmony_ci} 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_cistatic void setup(void) 74f08c3bdfSopenharmony_ci{ 75f08c3bdfSopenharmony_ci pgsz = getpagesize(); 76f08c3bdfSopenharmony_ci addr = SAFE_MMAP(NULL, pgsz, PROT_WRITE, 77f08c3bdfSopenharmony_ci MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 78f08c3bdfSopenharmony_ci} 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_cistatic void cleanup(void) 81f08c3bdfSopenharmony_ci{ 82f08c3bdfSopenharmony_ci if (addr) 83f08c3bdfSopenharmony_ci SAFE_MUNMAP(addr, pgsz); 84f08c3bdfSopenharmony_ci} 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_cistatic struct tst_test test = { 87f08c3bdfSopenharmony_ci .test_all = verify_mlock2, 88f08c3bdfSopenharmony_ci .setup = setup, 89f08c3bdfSopenharmony_ci .cleanup = cleanup, 90f08c3bdfSopenharmony_ci .needs_root = 1, 91f08c3bdfSopenharmony_ci}; 92