1// SPDX-License-Identifier: LGPL-2.1-or-later 2/* 3 * Copyright (C) 2005-2006 IBM Corporation. 4 * Author: Eric B Munson and Mel Gorman 5 */ 6 7/*\ 8 * [Description] 9 * 10 * madvise() on some kernels can cause the reservation counter to get 11 * corrupted. The problem is that the patches are allocated 12 * for the reservation but not faulted in at the time of allocation. The 13 * counters do not get updated and effectively "leak". This test 14 * identifies whether the kernel is vulnerable to the problem or not. 15 * It is fixed in kernel by commit f2deae9d4e70 16 */ 17 18#define _GNU_SOURCE 19#include <stdio.h> 20#include <sys/mount.h> 21#include <limits.h> 22#include <sys/param.h> 23#include <sys/types.h> 24 25#include "hugetlb.h" 26 27#define MNTPOINT "hugetlbfs/" 28static int fd = -1; 29static long hpage_size; 30 31static void run_test(void) 32{ 33 void *p; 34 unsigned long initial_rsvd, map_rsvd, madvise_rsvd, end_rsvd; 35 36 fd = tst_creat_unlinked(MNTPOINT, 0); 37 38 initial_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 39 tst_res(TINFO, "Reserve count before map: %lu", initial_rsvd); 40 41 p = SAFE_MMAP(NULL, hpage_size, PROT_READ|PROT_WRITE, MAP_SHARED, 42 fd, 0); 43 map_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 44 tst_res(TINFO, "Reserve count after map: %lu", map_rsvd); 45 46 if (madvise(p, hpage_size, MADV_WILLNEED) == -1) 47 tst_brk(TBROK|TERRNO, "madvise()"); 48 madvise_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 49 tst_res(TINFO, "Reserve count after madvise: %lu", madvise_rsvd); 50 51 SAFE_MUNMAP(p, hpage_size); 52 SAFE_CLOSE(fd); 53 end_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 54 tst_res(TINFO, "Reserve count after close(): %lu", end_rsvd); 55 56 TST_EXP_EQ_LU(end_rsvd, initial_rsvd); 57} 58 59static void setup(void) 60{ 61 hpage_size = SAFE_READ_MEMINFO("Hugepagesize:")*1024; 62} 63 64static void cleanup(void) 65{ 66 if (fd >= 0) 67 SAFE_CLOSE(fd); 68} 69 70static struct tst_test test = { 71 .tags = (struct tst_tag[]) { 72 {"linux-git", "f2deae9d4e70"}, 73 {} 74 }, 75 .needs_root = 1, 76 .mntpoint = MNTPOINT, 77 .needs_hugetlbfs = 1, 78 .needs_tmpdir = 1, 79 .setup = setup, 80 .cleanup = cleanup, 81 .test_all = run_test, 82 .hugepages = {1, TST_NEEDS}, 83}; 84