1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "qemu/osdep.h"
28#include "qemu-common.h"
29#include "exec/cpu-common.h"
30#include "sysemu/kvm.h"
31#include "sysemu/balloon.h"
32#include "trace-root.h"
33#include "qmp-commands.h"
34#include "qapi/qmp/qerror.h"
35#include "qapi/qmp/qjson.h"
36
37static QEMUBalloonEvent *balloon_event_fn;
38static QEMUBalloonStatus *balloon_stat_fn;
39static void *balloon_opaque;
40static bool balloon_inhibited;
41
42bool qemu_balloon_is_inhibited(void)
43{
44 return balloon_inhibited;
45}
46
47void qemu_balloon_inhibit(bool state)
48{
49 balloon_inhibited = state;
50}
51
52static bool have_balloon(Error **errp)
53{
54 if (kvm_enabled() && !kvm_has_sync_mmu()) {
55 error_set(errp, ERROR_CLASS_KVM_MISSING_CAP,
56 "Using KVM without synchronous MMU, balloon unavailable");
57 return false;
58 }
59 if (!balloon_event_fn) {
60 error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
61 "No balloon device has been activated");
62 return false;
63 }
64 return true;
65}
66
67int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
68 QEMUBalloonStatus *stat_func, void *opaque)
69{
70 if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
71
72
73
74 return -1;
75 }
76 balloon_event_fn = event_func;
77 balloon_stat_fn = stat_func;
78 balloon_opaque = opaque;
79 return 0;
80}
81
82void qemu_remove_balloon_handler(void *opaque)
83{
84 if (balloon_opaque != opaque) {
85 return;
86 }
87 balloon_event_fn = NULL;
88 balloon_stat_fn = NULL;
89 balloon_opaque = NULL;
90}
91
92BalloonInfo *qmp_query_balloon(Error **errp)
93{
94 BalloonInfo *info;
95
96 if (!have_balloon(errp)) {
97 return NULL;
98 }
99
100 info = g_malloc0(sizeof(*info));
101 balloon_stat_fn(balloon_opaque, info);
102 return info;
103}
104
105void qmp_balloon(int64_t target, Error **errp)
106{
107 if (!have_balloon(errp)) {
108 return;
109 }
110
111 if (target <= 0) {
112 error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "target", "a size");
113 return;
114 }
115
116 trace_balloon_event(balloon_opaque, target);
117 balloon_event_fn(balloon_opaque, target);
118}
119