xref: /kvmtool/util/util.c (revision f8edca99fb397f085fcb5948e0354e1d1e38ba43)
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 
761061257SMatt Evans #include <linux/magic.h>	/* For HUGETLBFS_MAGIC */
861061257SMatt Evans #include <sys/mman.h>
961061257SMatt Evans #include <sys/stat.h>
1061061257SMatt Evans #include <sys/statfs.h>
1161061257SMatt Evans 
12ad054a21SCyrill Gorcunov static void report(const char *prefix, const char *err, va_list params)
13ad054a21SCyrill Gorcunov {
14ad054a21SCyrill Gorcunov 	char msg[1024];
15ad054a21SCyrill Gorcunov 	vsnprintf(msg, sizeof(msg), err, params);
16ad054a21SCyrill Gorcunov 	fprintf(stderr, " %s%s\n", prefix, msg);
17ad054a21SCyrill Gorcunov }
18ad054a21SCyrill Gorcunov 
19ad054a21SCyrill Gorcunov static NORETURN void die_builtin(const char *err, va_list params)
20ad054a21SCyrill Gorcunov {
21ad054a21SCyrill Gorcunov 	report(" Fatal: ", err, params);
22ad054a21SCyrill Gorcunov 	exit(128);
23ad054a21SCyrill Gorcunov }
24ad054a21SCyrill Gorcunov 
25ad054a21SCyrill Gorcunov static void error_builtin(const char *err, va_list params)
26ad054a21SCyrill Gorcunov {
27ad054a21SCyrill Gorcunov 	report(" Error: ", err, params);
28ad054a21SCyrill Gorcunov }
29ad054a21SCyrill Gorcunov 
30ad054a21SCyrill Gorcunov static void warn_builtin(const char *warn, va_list params)
31ad054a21SCyrill Gorcunov {
32ad054a21SCyrill Gorcunov 	report(" Warning: ", warn, params);
33ad054a21SCyrill Gorcunov }
34ad054a21SCyrill Gorcunov 
3507f9d0dbSCyrill Gorcunov static void info_builtin(const char *info, va_list params)
3607f9d0dbSCyrill Gorcunov {
3707f9d0dbSCyrill Gorcunov 	report(" Info: ", info, params);
3807f9d0dbSCyrill Gorcunov }
3907f9d0dbSCyrill Gorcunov 
40ad054a21SCyrill Gorcunov void die(const char *err, ...)
41ad054a21SCyrill Gorcunov {
42ad054a21SCyrill Gorcunov 	va_list params;
43ad054a21SCyrill Gorcunov 
44ad054a21SCyrill Gorcunov 	va_start(params, err);
45ad054a21SCyrill Gorcunov 	die_builtin(err, params);
46ad054a21SCyrill Gorcunov 	va_end(params);
47ad054a21SCyrill Gorcunov }
48ad054a21SCyrill Gorcunov 
49599ed2a8SCyrill Gorcunov int pr_err(const char *err, ...)
50ad054a21SCyrill Gorcunov {
51ad054a21SCyrill Gorcunov 	va_list params;
52ad054a21SCyrill Gorcunov 
53ad054a21SCyrill Gorcunov 	va_start(params, err);
54ad054a21SCyrill Gorcunov 	error_builtin(err, params);
55ad054a21SCyrill Gorcunov 	va_end(params);
56ad054a21SCyrill Gorcunov 	return -1;
57ad054a21SCyrill Gorcunov }
58ad054a21SCyrill Gorcunov 
594542f276SCyrill Gorcunov void pr_warning(const char *warn, ...)
60ad054a21SCyrill Gorcunov {
61ad054a21SCyrill Gorcunov 	va_list params;
62ad054a21SCyrill Gorcunov 
63ad054a21SCyrill Gorcunov 	va_start(params, warn);
64ad054a21SCyrill Gorcunov 	warn_builtin(warn, params);
65ad054a21SCyrill Gorcunov 	va_end(params);
66ad054a21SCyrill Gorcunov }
67ad054a21SCyrill Gorcunov 
684542f276SCyrill Gorcunov void pr_info(const char *info, ...)
6907f9d0dbSCyrill Gorcunov {
7007f9d0dbSCyrill Gorcunov 	va_list params;
7107f9d0dbSCyrill Gorcunov 
7207f9d0dbSCyrill Gorcunov 	va_start(params, info);
7307f9d0dbSCyrill Gorcunov 	info_builtin(info, params);
7407f9d0dbSCyrill Gorcunov 	va_end(params);
7507f9d0dbSCyrill Gorcunov }
7607f9d0dbSCyrill Gorcunov 
77ad054a21SCyrill Gorcunov void die_perror(const char *s)
78ad054a21SCyrill Gorcunov {
79ad054a21SCyrill Gorcunov 	perror(s);
80ad054a21SCyrill Gorcunov 	exit(1);
81ad054a21SCyrill Gorcunov }
8261061257SMatt Evans 
8361061257SMatt Evans void *mmap_hugetlbfs(const char *htlbfs_path, u64 size)
8461061257SMatt Evans {
8561061257SMatt Evans 	char mpath[PATH_MAX];
8661061257SMatt Evans 	int fd;
8761061257SMatt Evans 	struct statfs sfs;
8861061257SMatt Evans 	void *addr;
8978682c28SMatt Evans 	unsigned long blk_size;
9061061257SMatt Evans 
9161061257SMatt Evans 	if (statfs(htlbfs_path, &sfs) < 0)
9261061257SMatt Evans 		die("Can't stat %s\n", htlbfs_path);
9361061257SMatt Evans 
943a60be06SSasha Levin 	if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC)
9561061257SMatt Evans 		die("%s is not hugetlbfs!\n", htlbfs_path);
9661061257SMatt Evans 
9778682c28SMatt Evans 	blk_size = (unsigned long)sfs.f_bsize;
9878682c28SMatt Evans 	if (sfs.f_bsize == 0 || blk_size > size) {
9961061257SMatt Evans 		die("Can't use hugetlbfs pagesize %ld for mem size %lld\n",
10078682c28SMatt Evans 		    blk_size, size);
10161061257SMatt Evans 	}
10261061257SMatt Evans 
10361061257SMatt Evans 	snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path);
10461061257SMatt Evans 	fd = mkstemp(mpath);
10561061257SMatt Evans 	if (fd < 0)
10661061257SMatt Evans 		die("Can't open %s for hugetlbfs map\n", mpath);
10761061257SMatt Evans 	unlink(mpath);
10861061257SMatt Evans 	if (ftruncate(fd, size) < 0)
10961061257SMatt Evans 		die("Can't ftruncate for mem mapping size %lld\n",
11061061257SMatt Evans 		    size);
11161061257SMatt Evans 	addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0);
11261061257SMatt Evans 	close(fd);
11361061257SMatt Evans 
11461061257SMatt Evans 	return addr;
11561061257SMatt Evans }
116*f8edca99SMichael Ellerman 
117*f8edca99SMichael Ellerman /* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */
118*f8edca99SMichael Ellerman void *mmap_anon_or_hugetlbfs(const char *hugetlbfs_path, u64 size)
119*f8edca99SMichael Ellerman {
120*f8edca99SMichael Ellerman 	if (hugetlbfs_path)
121*f8edca99SMichael Ellerman 		/*
122*f8edca99SMichael Ellerman 		 * We don't /need/ to map guest RAM from hugetlbfs, but we do so
123*f8edca99SMichael Ellerman 		 * if the user specifies a hugetlbfs path.
124*f8edca99SMichael Ellerman 		 */
125*f8edca99SMichael Ellerman 		return mmap_hugetlbfs(hugetlbfs_path, size);
126*f8edca99SMichael Ellerman 	else
127*f8edca99SMichael Ellerman 		return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
128*f8edca99SMichael Ellerman }
129