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

map_hugetlb.c (2445B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Example of using hugepage memory in a user application using the mmap
      4 * system call with MAP_HUGETLB flag.  Before running this program make
      5 * sure the administrator has allocated enough default sized huge pages
      6 * to cover the 256 MB allocation.
      7 *
      8 * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
      9 * That means the addresses starting with 0x800000... will need to be
     10 * specified.  Specifying a fixed address is not required on ppc64, i386
     11 * or x86_64.
     12 */
     13#include <stdlib.h>
     14#include <stdio.h>
     15#include <unistd.h>
     16#include <sys/mman.h>
     17#include <fcntl.h>
     18
     19#define LENGTH (256UL*1024*1024)
     20#define PROTECTION (PROT_READ | PROT_WRITE)
     21
     22#ifndef MAP_HUGETLB
     23#define MAP_HUGETLB 0x40000 /* arch specific */
     24#endif
     25
     26#ifndef MAP_HUGE_SHIFT
     27#define MAP_HUGE_SHIFT 26
     28#endif
     29
     30#ifndef MAP_HUGE_MASK
     31#define MAP_HUGE_MASK 0x3f
     32#endif
     33
     34/* Only ia64 requires this */
     35#ifdef __ia64__
     36#define ADDR (void *)(0x8000000000000000UL)
     37#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
     38#else
     39#define ADDR (void *)(0x0UL)
     40#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
     41#endif
     42
     43static void check_bytes(char *addr)
     44{
     45	printf("First hex is %x\n", *((unsigned int *)addr));
     46}
     47
     48static void write_bytes(char *addr, size_t length)
     49{
     50	unsigned long i;
     51
     52	for (i = 0; i < length; i++)
     53		*(addr + i) = (char)i;
     54}
     55
     56static int read_bytes(char *addr, size_t length)
     57{
     58	unsigned long i;
     59
     60	check_bytes(addr);
     61	for (i = 0; i < length; i++)
     62		if (*(addr + i) != (char)i) {
     63			printf("Mismatch at %lu\n", i);
     64			return 1;
     65		}
     66	return 0;
     67}
     68
     69int main(int argc, char **argv)
     70{
     71	void *addr;
     72	int ret;
     73	size_t length = LENGTH;
     74	int flags = FLAGS;
     75	int shift = 0;
     76
     77	if (argc > 1)
     78		length = atol(argv[1]) << 20;
     79	if (argc > 2) {
     80		shift = atoi(argv[2]);
     81		if (shift)
     82			flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
     83	}
     84
     85	if (shift)
     86		printf("%u kB hugepages\n", 1 << (shift - 10));
     87	else
     88		printf("Default size hugepages\n");
     89	printf("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
     90
     91	addr = mmap(ADDR, length, PROTECTION, flags, -1, 0);
     92	if (addr == MAP_FAILED) {
     93		perror("mmap");
     94		exit(1);
     95	}
     96
     97	printf("Returned address is %p\n", addr);
     98	check_bytes(addr);
     99	write_bytes(addr, length);
    100	ret = read_bytes(addr, length);
    101
    102	/* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
    103	if (munmap(addr, length)) {
    104		perror("munmap");
    105		exit(1);
    106	}
    107
    108	return ret;
    109}