1// SPDX-License-Identifier: LGPL-2.1-or-later 2/* 3 * Copyright (C) 2005-2006 IBM Corporation. 4 * Author: Mel Gorman 5 */ 6 7/*\ 8 * [Description] 9 * 10 * fadvise() on some kernels can cause the reservation counter to get 11 * corrupted. The problem is that the patches are allocated for the 12 * reservation but not faulted in at the time of allocation. The counters 13 * do not get updated and effectively "leak". This test identifies whether 14 * the kernel is vulnerable to the problem or not. It's fixed in kernel 15 * by commit f2deae9d4e70793568ef9e85d227abb7bef5b622. 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 long hpage_size; 29static int fd = -1; 30 31static void run_test(void) 32{ 33 void *p; 34 unsigned long initial_rsvd, map_rsvd, fadvise_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 SAFE_POSIX_FADVISE(fd, 0, hpage_size, POSIX_FADV_WILLNEED); 47 fadvise_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 48 tst_res(TINFO, "Reserve count after fadvise: %lu", fadvise_rsvd); 49 50 memset(p, 1, hpage_size); 51 52 SAFE_MUNMAP(p, hpage_size); 53 SAFE_CLOSE(fd); 54 end_rsvd = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD); 55 tst_res(TINFO, "Reserve count after close: %lu", end_rsvd); 56 57 TST_EXP_EQ_LU(end_rsvd, initial_rsvd); 58} 59 60static void setup(void) 61{ 62 hpage_size = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SIZE)*1024; 63} 64 65static void cleanup(void) 66{ 67 if (fd > 0) 68 SAFE_CLOSE(fd); 69} 70 71static struct tst_test test = { 72 .tags = (struct tst_tag[]) { 73 {"linux-git", "f2deae9d4e70"}, 74 {} 75 }, 76 .needs_root = 1, 77 .mntpoint = MNTPOINT, 78 .needs_hugetlbfs = 1, 79 .setup = setup, 80 .cleanup = cleanup, 81 .test_all = run_test, 82 .hugepages = {1, TST_NEEDS}, 83}; 84