cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

va_128TBswitch.c (6792B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *
      4 * Authors: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
      5 * Authors: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
      6 */
      7
      8#include <stdio.h>
      9#include <sys/mman.h>
     10#include <string.h>
     11
     12#include "../kselftest.h"
     13
     14#ifdef __powerpc64__
     15#define PAGE_SIZE	(64 << 10)
     16/*
     17 * This will work with 16M and 2M hugepage size
     18 */
     19#define HUGETLB_SIZE	(16 << 20)
     20#else
     21#define PAGE_SIZE	(4 << 10)
     22#define HUGETLB_SIZE	(2 << 20)
     23#endif
     24
     25/*
     26 * >= 128TB is the hint addr value we used to select
     27 * large address space.
     28 */
     29#define ADDR_SWITCH_HINT (1UL << 47)
     30#define LOW_ADDR	((void *) (1UL << 30))
     31#define HIGH_ADDR	((void *) (1UL << 48))
     32
     33struct testcase {
     34	void *addr;
     35	unsigned long size;
     36	unsigned long flags;
     37	const char *msg;
     38	unsigned int low_addr_required:1;
     39	unsigned int keep_mapped:1;
     40};
     41
     42static struct testcase testcases[] = {
     43	{
     44		/*
     45		 * If stack is moved, we could possibly allocate
     46		 * this at the requested address.
     47		 */
     48		.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
     49		.size = PAGE_SIZE,
     50		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
     51		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
     52		.low_addr_required = 1,
     53	},
     54	{
     55		/*
     56		 * We should never allocate at the requested address or above it
     57		 * The len cross the 128TB boundary. Without MAP_FIXED
     58		 * we will always search in the lower address space.
     59		 */
     60		.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
     61		.size = 2 * PAGE_SIZE,
     62		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
     63		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, (2 * PAGE_SIZE))",
     64		.low_addr_required = 1,
     65	},
     66	{
     67		/*
     68		 * Exact mapping at 128TB, the area is free we should get that
     69		 * even without MAP_FIXED.
     70		 */
     71		.addr = ((void *)(ADDR_SWITCH_HINT)),
     72		.size = PAGE_SIZE,
     73		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
     74		.msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
     75		.keep_mapped = 1,
     76	},
     77	{
     78		.addr = (void *)(ADDR_SWITCH_HINT),
     79		.size = 2 * PAGE_SIZE,
     80		.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
     81		.msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
     82	},
     83	{
     84		.addr = NULL,
     85		.size = 2 * PAGE_SIZE,
     86		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
     87		.msg = "mmap(NULL)",
     88		.low_addr_required = 1,
     89	},
     90	{
     91		.addr = LOW_ADDR,
     92		.size = 2 * PAGE_SIZE,
     93		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
     94		.msg = "mmap(LOW_ADDR)",
     95		.low_addr_required = 1,
     96	},
     97	{
     98		.addr = HIGH_ADDR,
     99		.size = 2 * PAGE_SIZE,
    100		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    101		.msg = "mmap(HIGH_ADDR)",
    102		.keep_mapped = 1,
    103	},
    104	{
    105		.addr = HIGH_ADDR,
    106		.size = 2 * PAGE_SIZE,
    107		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    108		.msg = "mmap(HIGH_ADDR) again",
    109		.keep_mapped = 1,
    110	},
    111	{
    112		.addr = HIGH_ADDR,
    113		.size = 2 * PAGE_SIZE,
    114		.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
    115		.msg = "mmap(HIGH_ADDR, MAP_FIXED)",
    116	},
    117	{
    118		.addr = (void *) -1,
    119		.size = 2 * PAGE_SIZE,
    120		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    121		.msg = "mmap(-1)",
    122		.keep_mapped = 1,
    123	},
    124	{
    125		.addr = (void *) -1,
    126		.size = 2 * PAGE_SIZE,
    127		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    128		.msg = "mmap(-1) again",
    129	},
    130	{
    131		.addr = ((void *)(ADDR_SWITCH_HINT - PAGE_SIZE)),
    132		.size = PAGE_SIZE,
    133		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    134		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, PAGE_SIZE)",
    135		.low_addr_required = 1,
    136	},
    137	{
    138		.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
    139		.size = 2 * PAGE_SIZE,
    140		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    141		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2 * PAGE_SIZE)",
    142		.low_addr_required = 1,
    143		.keep_mapped = 1,
    144	},
    145	{
    146		.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE / 2),
    147		.size = 2 * PAGE_SIZE,
    148		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    149		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE/2 , 2 * PAGE_SIZE)",
    150		.low_addr_required = 1,
    151		.keep_mapped = 1,
    152	},
    153	{
    154		.addr = ((void *)(ADDR_SWITCH_HINT)),
    155		.size = PAGE_SIZE,
    156		.flags = MAP_PRIVATE | MAP_ANONYMOUS,
    157		.msg = "mmap(ADDR_SWITCH_HINT, PAGE_SIZE)",
    158	},
    159	{
    160		.addr = (void *)(ADDR_SWITCH_HINT),
    161		.size = 2 * PAGE_SIZE,
    162		.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
    163		.msg = "mmap(ADDR_SWITCH_HINT, 2 * PAGE_SIZE, MAP_FIXED)",
    164	},
    165};
    166
    167static struct testcase hugetlb_testcases[] = {
    168	{
    169		.addr = NULL,
    170		.size = HUGETLB_SIZE,
    171		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    172		.msg = "mmap(NULL, MAP_HUGETLB)",
    173		.low_addr_required = 1,
    174	},
    175	{
    176		.addr = LOW_ADDR,
    177		.size = HUGETLB_SIZE,
    178		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    179		.msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
    180		.low_addr_required = 1,
    181	},
    182	{
    183		.addr = HIGH_ADDR,
    184		.size = HUGETLB_SIZE,
    185		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    186		.msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
    187		.keep_mapped = 1,
    188	},
    189	{
    190		.addr = HIGH_ADDR,
    191		.size = HUGETLB_SIZE,
    192		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    193		.msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
    194		.keep_mapped = 1,
    195	},
    196	{
    197		.addr = HIGH_ADDR,
    198		.size = HUGETLB_SIZE,
    199		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
    200		.msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
    201	},
    202	{
    203		.addr = (void *) -1,
    204		.size = HUGETLB_SIZE,
    205		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    206		.msg = "mmap(-1, MAP_HUGETLB)",
    207		.keep_mapped = 1,
    208	},
    209	{
    210		.addr = (void *) -1,
    211		.size = HUGETLB_SIZE,
    212		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    213		.msg = "mmap(-1, MAP_HUGETLB) again",
    214	},
    215	{
    216		.addr = (void *)(ADDR_SWITCH_HINT - PAGE_SIZE),
    217		.size = 2 * HUGETLB_SIZE,
    218		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
    219		.msg = "mmap(ADDR_SWITCH_HINT - PAGE_SIZE, 2*HUGETLB_SIZE, MAP_HUGETLB)",
    220		.low_addr_required = 1,
    221		.keep_mapped = 1,
    222	},
    223	{
    224		.addr = (void *)(ADDR_SWITCH_HINT),
    225		.size = 2 * HUGETLB_SIZE,
    226		.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
    227		.msg = "mmap(ADDR_SWITCH_HINT , 2*HUGETLB_SIZE, MAP_FIXED | MAP_HUGETLB)",
    228	},
    229};
    230
    231static int run_test(struct testcase *test, int count)
    232{
    233	void *p;
    234	int i, ret = 0;
    235
    236	for (i = 0; i < count; i++) {
    237		struct testcase *t = test + i;
    238
    239		p = mmap(t->addr, t->size, PROT_READ | PROT_WRITE, t->flags, -1, 0);
    240
    241		printf("%s: %p - ", t->msg, p);
    242
    243		if (p == MAP_FAILED) {
    244			printf("FAILED\n");
    245			ret = 1;
    246			continue;
    247		}
    248
    249		if (t->low_addr_required && p >= (void *)(ADDR_SWITCH_HINT)) {
    250			printf("FAILED\n");
    251			ret = 1;
    252		} else {
    253			/*
    254			 * Do a dereference of the address returned so that we catch
    255			 * bugs in page fault handling
    256			 */
    257			memset(p, 0, t->size);
    258			printf("OK\n");
    259		}
    260		if (!t->keep_mapped)
    261			munmap(p, t->size);
    262	}
    263
    264	return ret;
    265}
    266
    267static int supported_arch(void)
    268{
    269#if defined(__powerpc64__)
    270	return 1;
    271#elif defined(__x86_64__)
    272	return 1;
    273#else
    274	return 0;
    275#endif
    276}
    277
    278int main(int argc, char **argv)
    279{
    280	int ret;
    281
    282	if (!supported_arch())
    283		return 0;
    284
    285	ret = run_test(testcases, ARRAY_SIZE(testcases));
    286	if (argc == 2 && !strcmp(argv[1], "--run-hugetlb"))
    287		ret = run_test(hugetlb_testcases, ARRAY_SIZE(hugetlb_testcases));
    288	return ret;
    289}