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
report(const char * prefix,const char * err,va_list params)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
die_builtin(const char * err,va_list params)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
error_builtin(const char * err,va_list params)26ad054a21SCyrill Gorcunov static void error_builtin(const char *err, va_list params)
27ad054a21SCyrill Gorcunov {
28ad054a21SCyrill Gorcunov report(" Error: ", err, params);
29ad054a21SCyrill Gorcunov }
30ad054a21SCyrill Gorcunov
warn_builtin(const char * warn,va_list params)31ad054a21SCyrill Gorcunov static void warn_builtin(const char *warn, va_list params)
32ad054a21SCyrill Gorcunov {
33ad054a21SCyrill Gorcunov report(" Warning: ", warn, params);
34ad054a21SCyrill Gorcunov }
35ad054a21SCyrill Gorcunov
info_builtin(const char * info,va_list params)3607f9d0dbSCyrill Gorcunov static void info_builtin(const char *info, va_list params)
3707f9d0dbSCyrill Gorcunov {
3807f9d0dbSCyrill Gorcunov report(" Info: ", info, params);
3907f9d0dbSCyrill Gorcunov }
4007f9d0dbSCyrill Gorcunov
debug_builtin(const char * debug,va_list params)41fc184a68SAlexandru Elisei static void debug_builtin(const char *debug, va_list params)
42fc184a68SAlexandru Elisei {
43fc184a68SAlexandru Elisei report(" Debug: ", debug, params);
44fc184a68SAlexandru Elisei }
45fc184a68SAlexandru Elisei
die(const char * err,...)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
pr_err(const char * err,...)552cc4929cSAlexandru Elisei void pr_err(const char *err, ...)
56ad054a21SCyrill Gorcunov {
57ad054a21SCyrill Gorcunov va_list params;
58ad054a21SCyrill Gorcunov
59*bd4ba571SAlexandru Elisei if (loglevel < LOGLEVEL_ERROR)
60*bd4ba571SAlexandru Elisei return;
61*bd4ba571SAlexandru Elisei
62ad054a21SCyrill Gorcunov va_start(params, err);
63ad054a21SCyrill Gorcunov error_builtin(err, params);
64ad054a21SCyrill Gorcunov va_end(params);
65ad054a21SCyrill Gorcunov }
66ad054a21SCyrill Gorcunov
pr_warning(const char * warn,...)674542f276SCyrill Gorcunov void pr_warning(const char *warn, ...)
68ad054a21SCyrill Gorcunov {
69ad054a21SCyrill Gorcunov va_list params;
70ad054a21SCyrill Gorcunov
71*bd4ba571SAlexandru Elisei if (loglevel < LOGLEVEL_WARNING)
72*bd4ba571SAlexandru Elisei return;
73*bd4ba571SAlexandru Elisei
74ad054a21SCyrill Gorcunov va_start(params, warn);
75ad054a21SCyrill Gorcunov warn_builtin(warn, params);
76ad054a21SCyrill Gorcunov va_end(params);
77ad054a21SCyrill Gorcunov }
78ad054a21SCyrill Gorcunov
pr_info(const char * info,...)794542f276SCyrill Gorcunov void pr_info(const char *info, ...)
8007f9d0dbSCyrill Gorcunov {
8107f9d0dbSCyrill Gorcunov va_list params;
8207f9d0dbSCyrill Gorcunov
83*bd4ba571SAlexandru Elisei if (loglevel < LOGLEVEL_INFO)
84*bd4ba571SAlexandru Elisei return;
85*bd4ba571SAlexandru Elisei
8607f9d0dbSCyrill Gorcunov va_start(params, info);
8707f9d0dbSCyrill Gorcunov info_builtin(info, params);
8807f9d0dbSCyrill Gorcunov va_end(params);
8907f9d0dbSCyrill Gorcunov }
9007f9d0dbSCyrill Gorcunov
91fc184a68SAlexandru Elisei /* Do not call directly; call pr_debug() instead. */
__pr_debug(const char * debug,...)92fc184a68SAlexandru Elisei void __pr_debug(const char *debug, ...)
93fc184a68SAlexandru Elisei {
94fc184a68SAlexandru Elisei va_list params;
95fc184a68SAlexandru Elisei
96fc184a68SAlexandru Elisei va_start(params, debug);
97fc184a68SAlexandru Elisei debug_builtin(debug, params);
98fc184a68SAlexandru Elisei va_end(params);
99fc184a68SAlexandru Elisei }
100fc184a68SAlexandru Elisei
die_perror(const char * s)101ad054a21SCyrill Gorcunov void die_perror(const char *s)
102ad054a21SCyrill Gorcunov {
103ad054a21SCyrill Gorcunov perror(s);
104ad054a21SCyrill Gorcunov exit(1);
105ad054a21SCyrill Gorcunov }
10661061257SMatt Evans
mmap_hugetlbfs(struct kvm * kvm,const char * htlbfs_path,u64 size)1073ebd8e0bSMichael Ellerman void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size)
10861061257SMatt Evans {
10961061257SMatt Evans char mpath[PATH_MAX];
11061061257SMatt Evans int fd;
11161061257SMatt Evans struct statfs sfs;
11261061257SMatt Evans void *addr;
11378682c28SMatt Evans unsigned long blk_size;
11461061257SMatt Evans
11561061257SMatt Evans if (statfs(htlbfs_path, &sfs) < 0)
11661061257SMatt Evans die("Can't stat %s\n", htlbfs_path);
11761061257SMatt Evans
1183a60be06SSasha Levin if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC)
11961061257SMatt Evans die("%s is not hugetlbfs!\n", htlbfs_path);
12061061257SMatt Evans
12178682c28SMatt Evans blk_size = (unsigned long)sfs.f_bsize;
12278682c28SMatt Evans if (sfs.f_bsize == 0 || blk_size > size) {
12361061257SMatt Evans die("Can't use hugetlbfs pagesize %ld for mem size %lld\n",
12469f50425SAndreas Herrmann blk_size, (unsigned long long)size);
12561061257SMatt Evans }
12661061257SMatt Evans
1273ebd8e0bSMichael Ellerman kvm->ram_pagesize = blk_size;
1283ebd8e0bSMichael Ellerman
12961061257SMatt Evans snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path);
13061061257SMatt Evans fd = mkstemp(mpath);
13161061257SMatt Evans if (fd < 0)
13261061257SMatt Evans die("Can't open %s for hugetlbfs map\n", mpath);
13361061257SMatt Evans unlink(mpath);
13461061257SMatt Evans if (ftruncate(fd, size) < 0)
13561061257SMatt Evans die("Can't ftruncate for mem mapping size %lld\n",
13669f50425SAndreas Herrmann (unsigned long long)size);
13761061257SMatt Evans addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0);
13861061257SMatt Evans close(fd);
13961061257SMatt Evans
14061061257SMatt Evans return addr;
14161061257SMatt Evans }
142f8edca99SMichael Ellerman
143f8edca99SMichael Ellerman /* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */
mmap_anon_or_hugetlbfs(struct kvm * kvm,const char * hugetlbfs_path,u64 size)1443ebd8e0bSMichael Ellerman void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size)
145f8edca99SMichael Ellerman {
146f8edca99SMichael Ellerman if (hugetlbfs_path)
147f8edca99SMichael Ellerman /*
148f8edca99SMichael Ellerman * We don't /need/ to map guest RAM from hugetlbfs, but we do so
149f8edca99SMichael Ellerman * if the user specifies a hugetlbfs path.
150f8edca99SMichael Ellerman */
1513ebd8e0bSMichael Ellerman return mmap_hugetlbfs(kvm, hugetlbfs_path, size);
1523ebd8e0bSMichael Ellerman else {
1533ebd8e0bSMichael Ellerman kvm->ram_pagesize = getpagesize();
154f8edca99SMichael Ellerman return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
155f8edca99SMichael Ellerman }
1563ebd8e0bSMichael Ellerman }
157