1ad054a21SCyrill Gorcunov /* 2ad054a21SCyrill Gorcunov * Taken from perf which in turn take it from GIT 3ad054a21SCyrill Gorcunov */ 4ad054a21SCyrill Gorcunov 5f3150089SPekka Enberg #include "kvm/util.h" 6ad054a21SCyrill Gorcunov 73ebd8e0bSMichael Ellerman #include <kvm/kvm.h> 861061257SMatt Evans #include <linux/magic.h> /* For HUGETLBFS_MAGIC */ 961061257SMatt Evans #include <sys/mman.h> 1061061257SMatt Evans #include <sys/stat.h> 1161061257SMatt Evans #include <sys/statfs.h> 1261061257SMatt Evans 13ad054a21SCyrill Gorcunov static void report(const char *prefix, const char *err, va_list params) 14ad054a21SCyrill Gorcunov { 15ad054a21SCyrill Gorcunov char msg[1024]; 16ad054a21SCyrill Gorcunov vsnprintf(msg, sizeof(msg), err, params); 17ad054a21SCyrill Gorcunov fprintf(stderr, " %s%s\n", prefix, msg); 18ad054a21SCyrill Gorcunov } 19ad054a21SCyrill Gorcunov 20ad054a21SCyrill Gorcunov static NORETURN void die_builtin(const char *err, va_list params) 21ad054a21SCyrill Gorcunov { 22ad054a21SCyrill Gorcunov report(" Fatal: ", err, params); 23ad054a21SCyrill Gorcunov exit(128); 24ad054a21SCyrill Gorcunov } 25ad054a21SCyrill Gorcunov 26ad054a21SCyrill Gorcunov static void error_builtin(const char *err, va_list params) 27ad054a21SCyrill Gorcunov { 28ad054a21SCyrill Gorcunov report(" Error: ", err, params); 29ad054a21SCyrill Gorcunov } 30ad054a21SCyrill Gorcunov 31ad054a21SCyrill Gorcunov static void warn_builtin(const char *warn, va_list params) 32ad054a21SCyrill Gorcunov { 33ad054a21SCyrill Gorcunov report(" Warning: ", warn, params); 34ad054a21SCyrill Gorcunov } 35ad054a21SCyrill Gorcunov 3607f9d0dbSCyrill Gorcunov static void info_builtin(const char *info, va_list params) 3707f9d0dbSCyrill Gorcunov { 3807f9d0dbSCyrill Gorcunov report(" Info: ", info, params); 3907f9d0dbSCyrill Gorcunov } 4007f9d0dbSCyrill Gorcunov 41*fc184a68SAlexandru Elisei static void debug_builtin(const char *debug, va_list params) 42*fc184a68SAlexandru Elisei { 43*fc184a68SAlexandru Elisei report(" Debug: ", debug, params); 44*fc184a68SAlexandru Elisei } 45*fc184a68SAlexandru Elisei 46ad054a21SCyrill Gorcunov void die(const char *err, ...) 47ad054a21SCyrill Gorcunov { 48ad054a21SCyrill Gorcunov va_list params; 49ad054a21SCyrill Gorcunov 50ad054a21SCyrill Gorcunov va_start(params, err); 51ad054a21SCyrill Gorcunov die_builtin(err, params); 52ad054a21SCyrill Gorcunov va_end(params); 53ad054a21SCyrill Gorcunov } 54ad054a21SCyrill Gorcunov 552cc4929cSAlexandru Elisei void pr_err(const char *err, ...) 56ad054a21SCyrill Gorcunov { 57ad054a21SCyrill Gorcunov va_list params; 58ad054a21SCyrill Gorcunov 59ad054a21SCyrill Gorcunov va_start(params, err); 60ad054a21SCyrill Gorcunov error_builtin(err, params); 61ad054a21SCyrill Gorcunov va_end(params); 62ad054a21SCyrill Gorcunov } 63ad054a21SCyrill Gorcunov 644542f276SCyrill Gorcunov void pr_warning(const char *warn, ...) 65ad054a21SCyrill Gorcunov { 66ad054a21SCyrill Gorcunov va_list params; 67ad054a21SCyrill Gorcunov 68ad054a21SCyrill Gorcunov va_start(params, warn); 69ad054a21SCyrill Gorcunov warn_builtin(warn, params); 70ad054a21SCyrill Gorcunov va_end(params); 71ad054a21SCyrill Gorcunov } 72ad054a21SCyrill Gorcunov 734542f276SCyrill Gorcunov void pr_info(const char *info, ...) 7407f9d0dbSCyrill Gorcunov { 7507f9d0dbSCyrill Gorcunov va_list params; 7607f9d0dbSCyrill Gorcunov 7707f9d0dbSCyrill Gorcunov va_start(params, info); 7807f9d0dbSCyrill Gorcunov info_builtin(info, params); 7907f9d0dbSCyrill Gorcunov va_end(params); 8007f9d0dbSCyrill Gorcunov } 8107f9d0dbSCyrill Gorcunov 82*fc184a68SAlexandru Elisei /* Do not call directly; call pr_debug() instead. */ 83*fc184a68SAlexandru Elisei void __pr_debug(const char *debug, ...) 84*fc184a68SAlexandru Elisei { 85*fc184a68SAlexandru Elisei va_list params; 86*fc184a68SAlexandru Elisei 87*fc184a68SAlexandru Elisei va_start(params, debug); 88*fc184a68SAlexandru Elisei debug_builtin(debug, params); 89*fc184a68SAlexandru Elisei va_end(params); 90*fc184a68SAlexandru Elisei } 91*fc184a68SAlexandru Elisei 92ad054a21SCyrill Gorcunov void die_perror(const char *s) 93ad054a21SCyrill Gorcunov { 94ad054a21SCyrill Gorcunov perror(s); 95ad054a21SCyrill Gorcunov exit(1); 96ad054a21SCyrill Gorcunov } 9761061257SMatt Evans 983ebd8e0bSMichael Ellerman void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size) 9961061257SMatt Evans { 10061061257SMatt Evans char mpath[PATH_MAX]; 10161061257SMatt Evans int fd; 10261061257SMatt Evans struct statfs sfs; 10361061257SMatt Evans void *addr; 10478682c28SMatt Evans unsigned long blk_size; 10561061257SMatt Evans 10661061257SMatt Evans if (statfs(htlbfs_path, &sfs) < 0) 10761061257SMatt Evans die("Can't stat %s\n", htlbfs_path); 10861061257SMatt Evans 1093a60be06SSasha Levin if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC) 11061061257SMatt Evans die("%s is not hugetlbfs!\n", htlbfs_path); 11161061257SMatt Evans 11278682c28SMatt Evans blk_size = (unsigned long)sfs.f_bsize; 11378682c28SMatt Evans if (sfs.f_bsize == 0 || blk_size > size) { 11461061257SMatt Evans die("Can't use hugetlbfs pagesize %ld for mem size %lld\n", 11569f50425SAndreas Herrmann blk_size, (unsigned long long)size); 11661061257SMatt Evans } 11761061257SMatt Evans 1183ebd8e0bSMichael Ellerman kvm->ram_pagesize = blk_size; 1193ebd8e0bSMichael Ellerman 12061061257SMatt Evans snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path); 12161061257SMatt Evans fd = mkstemp(mpath); 12261061257SMatt Evans if (fd < 0) 12361061257SMatt Evans die("Can't open %s for hugetlbfs map\n", mpath); 12461061257SMatt Evans unlink(mpath); 12561061257SMatt Evans if (ftruncate(fd, size) < 0) 12661061257SMatt Evans die("Can't ftruncate for mem mapping size %lld\n", 12769f50425SAndreas Herrmann (unsigned long long)size); 12861061257SMatt Evans addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0); 12961061257SMatt Evans close(fd); 13061061257SMatt Evans 13161061257SMatt Evans return addr; 13261061257SMatt Evans } 133f8edca99SMichael Ellerman 134f8edca99SMichael Ellerman /* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */ 1353ebd8e0bSMichael Ellerman void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size) 136f8edca99SMichael Ellerman { 137f8edca99SMichael Ellerman if (hugetlbfs_path) 138f8edca99SMichael Ellerman /* 139f8edca99SMichael Ellerman * We don't /need/ to map guest RAM from hugetlbfs, but we do so 140f8edca99SMichael Ellerman * if the user specifies a hugetlbfs path. 141f8edca99SMichael Ellerman */ 1423ebd8e0bSMichael Ellerman return mmap_hugetlbfs(kvm, hugetlbfs_path, size); 1433ebd8e0bSMichael Ellerman else { 1443ebd8e0bSMichael Ellerman kvm->ram_pagesize = getpagesize(); 145f8edca99SMichael Ellerman return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 146f8edca99SMichael Ellerman } 1473ebd8e0bSMichael Ellerman } 148