1 /* 2 * Taken from perf which in turn take it from GIT 3 */ 4 5 #include "kvm/util.h" 6 7 #include <kvm/kvm.h> 8 #include <linux/magic.h> /* For HUGETLBFS_MAGIC */ 9 #include <sys/mman.h> 10 #include <sys/stat.h> 11 #include <sys/statfs.h> 12 13 static void report(const char *prefix, const char *err, va_list params) 14 { 15 char msg[1024]; 16 vsnprintf(msg, sizeof(msg), err, params); 17 fprintf(stderr, " %s%s\n", prefix, msg); 18 } 19 20 static NORETURN void die_builtin(const char *err, va_list params) 21 { 22 report(" Fatal: ", err, params); 23 exit(128); 24 } 25 26 static void error_builtin(const char *err, va_list params) 27 { 28 report(" Error: ", err, params); 29 } 30 31 static void warn_builtin(const char *warn, va_list params) 32 { 33 report(" Warning: ", warn, params); 34 } 35 36 static void info_builtin(const char *info, va_list params) 37 { 38 report(" Info: ", info, params); 39 } 40 41 static void debug_builtin(const char *debug, va_list params) 42 { 43 report(" Debug: ", debug, params); 44 } 45 46 void die(const char *err, ...) 47 { 48 va_list params; 49 50 va_start(params, err); 51 die_builtin(err, params); 52 va_end(params); 53 } 54 55 void pr_err(const char *err, ...) 56 { 57 va_list params; 58 59 va_start(params, err); 60 error_builtin(err, params); 61 va_end(params); 62 } 63 64 void pr_warning(const char *warn, ...) 65 { 66 va_list params; 67 68 va_start(params, warn); 69 warn_builtin(warn, params); 70 va_end(params); 71 } 72 73 void pr_info(const char *info, ...) 74 { 75 va_list params; 76 77 va_start(params, info); 78 info_builtin(info, params); 79 va_end(params); 80 } 81 82 /* Do not call directly; call pr_debug() instead. */ 83 void __pr_debug(const char *debug, ...) 84 { 85 va_list params; 86 87 va_start(params, debug); 88 debug_builtin(debug, params); 89 va_end(params); 90 } 91 92 void die_perror(const char *s) 93 { 94 perror(s); 95 exit(1); 96 } 97 98 void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size) 99 { 100 char mpath[PATH_MAX]; 101 int fd; 102 struct statfs sfs; 103 void *addr; 104 unsigned long blk_size; 105 106 if (statfs(htlbfs_path, &sfs) < 0) 107 die("Can't stat %s\n", htlbfs_path); 108 109 if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC) 110 die("%s is not hugetlbfs!\n", htlbfs_path); 111 112 blk_size = (unsigned long)sfs.f_bsize; 113 if (sfs.f_bsize == 0 || blk_size > size) { 114 die("Can't use hugetlbfs pagesize %ld for mem size %lld\n", 115 blk_size, (unsigned long long)size); 116 } 117 118 kvm->ram_pagesize = blk_size; 119 120 snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path); 121 fd = mkstemp(mpath); 122 if (fd < 0) 123 die("Can't open %s for hugetlbfs map\n", mpath); 124 unlink(mpath); 125 if (ftruncate(fd, size) < 0) 126 die("Can't ftruncate for mem mapping size %lld\n", 127 (unsigned long long)size); 128 addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0); 129 close(fd); 130 131 return addr; 132 } 133 134 /* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */ 135 void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size) 136 { 137 if (hugetlbfs_path) 138 /* 139 * We don't /need/ to map guest RAM from hugetlbfs, but we do so 140 * if the user specifies a hugetlbfs path. 141 */ 142 return mmap_hugetlbfs(kvm, hugetlbfs_path, size); 143 else { 144 kvm->ram_pagesize = getpagesize(); 145 return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 146 } 147 } 148