xref: /qemu/system/balloon.c (revision eeef44b3)
18d7f2e76SPhilippe Mathieu-Daudé /*
28d7f2e76SPhilippe Mathieu-Daudé  * Generic Balloon handlers and management
38d7f2e76SPhilippe Mathieu-Daudé  *
48d7f2e76SPhilippe Mathieu-Daudé  * Copyright (c) 2003-2008 Fabrice Bellard
58d7f2e76SPhilippe Mathieu-Daudé  * Copyright (C) 2011 Red Hat, Inc.
68d7f2e76SPhilippe Mathieu-Daudé  * Copyright (C) 2011 Amit Shah <amit.shah@redhat.com>
78d7f2e76SPhilippe Mathieu-Daudé  *
88d7f2e76SPhilippe Mathieu-Daudé  * Permission is hereby granted, free of charge, to any person obtaining a copy
98d7f2e76SPhilippe Mathieu-Daudé  * of this software and associated documentation files (the "Software"), to deal
108d7f2e76SPhilippe Mathieu-Daudé  * in the Software without restriction, including without limitation the rights
118d7f2e76SPhilippe Mathieu-Daudé  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
128d7f2e76SPhilippe Mathieu-Daudé  * copies of the Software, and to permit persons to whom the Software is
138d7f2e76SPhilippe Mathieu-Daudé  * furnished to do so, subject to the following conditions:
148d7f2e76SPhilippe Mathieu-Daudé  *
158d7f2e76SPhilippe Mathieu-Daudé  * The above copyright notice and this permission notice shall be included in
168d7f2e76SPhilippe Mathieu-Daudé  * all copies or substantial portions of the Software.
178d7f2e76SPhilippe Mathieu-Daudé  *
188d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
198d7f2e76SPhilippe Mathieu-Daudé  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
208d7f2e76SPhilippe Mathieu-Daudé  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
218d7f2e76SPhilippe Mathieu-Daudé  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
228d7f2e76SPhilippe Mathieu-Daudé  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
238d7f2e76SPhilippe Mathieu-Daudé  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
248d7f2e76SPhilippe Mathieu-Daudé  * THE SOFTWARE.
258d7f2e76SPhilippe Mathieu-Daudé  */
268d7f2e76SPhilippe Mathieu-Daudé 
278d7f2e76SPhilippe Mathieu-Daudé #include "qemu/osdep.h"
288d7f2e76SPhilippe Mathieu-Daudé #include "qemu/atomic.h"
298d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/kvm.h"
308d7f2e76SPhilippe Mathieu-Daudé #include "sysemu/balloon.h"
318d7f2e76SPhilippe Mathieu-Daudé #include "qapi/error.h"
328d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qapi-commands-machine.h"
338d7f2e76SPhilippe Mathieu-Daudé #include "qapi/qmp/qerror.h"
348d7f2e76SPhilippe Mathieu-Daudé #include "trace.h"
358d7f2e76SPhilippe Mathieu-Daudé 
368d7f2e76SPhilippe Mathieu-Daudé static QEMUBalloonEvent *balloon_event_fn;
378d7f2e76SPhilippe Mathieu-Daudé static QEMUBalloonStatus *balloon_stat_fn;
388d7f2e76SPhilippe Mathieu-Daudé static void *balloon_opaque;
398d7f2e76SPhilippe Mathieu-Daudé 
have_balloon(Error ** errp)408d7f2e76SPhilippe Mathieu-Daudé static bool have_balloon(Error **errp)
418d7f2e76SPhilippe Mathieu-Daudé {
428d7f2e76SPhilippe Mathieu-Daudé     if (kvm_enabled() && !kvm_has_sync_mmu()) {
438d7f2e76SPhilippe Mathieu-Daudé         error_set(errp, ERROR_CLASS_KVM_MISSING_CAP,
448d7f2e76SPhilippe Mathieu-Daudé                   "Using KVM without synchronous MMU, balloon unavailable");
458d7f2e76SPhilippe Mathieu-Daudé         return false;
468d7f2e76SPhilippe Mathieu-Daudé     }
478d7f2e76SPhilippe Mathieu-Daudé     if (!balloon_event_fn) {
488d7f2e76SPhilippe Mathieu-Daudé         error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
498d7f2e76SPhilippe Mathieu-Daudé                   "No balloon device has been activated");
508d7f2e76SPhilippe Mathieu-Daudé         return false;
518d7f2e76SPhilippe Mathieu-Daudé     }
528d7f2e76SPhilippe Mathieu-Daudé     return true;
538d7f2e76SPhilippe Mathieu-Daudé }
548d7f2e76SPhilippe Mathieu-Daudé 
qemu_add_balloon_handler(QEMUBalloonEvent * event_func,QEMUBalloonStatus * stat_func,void * opaque)558d7f2e76SPhilippe Mathieu-Daudé int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
568d7f2e76SPhilippe Mathieu-Daudé                              QEMUBalloonStatus *stat_func, void *opaque)
578d7f2e76SPhilippe Mathieu-Daudé {
588d7f2e76SPhilippe Mathieu-Daudé     if (balloon_event_fn || balloon_stat_fn || balloon_opaque) {
598d7f2e76SPhilippe Mathieu-Daudé         /* We're already registered one balloon handler.  How many can
608d7f2e76SPhilippe Mathieu-Daudé          * a guest really have?
618d7f2e76SPhilippe Mathieu-Daudé          */
628d7f2e76SPhilippe Mathieu-Daudé         return -1;
638d7f2e76SPhilippe Mathieu-Daudé     }
648d7f2e76SPhilippe Mathieu-Daudé     balloon_event_fn = event_func;
658d7f2e76SPhilippe Mathieu-Daudé     balloon_stat_fn = stat_func;
668d7f2e76SPhilippe Mathieu-Daudé     balloon_opaque = opaque;
678d7f2e76SPhilippe Mathieu-Daudé     return 0;
688d7f2e76SPhilippe Mathieu-Daudé }
698d7f2e76SPhilippe Mathieu-Daudé 
qemu_remove_balloon_handler(void * opaque)708d7f2e76SPhilippe Mathieu-Daudé void qemu_remove_balloon_handler(void *opaque)
718d7f2e76SPhilippe Mathieu-Daudé {
728d7f2e76SPhilippe Mathieu-Daudé     if (balloon_opaque != opaque) {
738d7f2e76SPhilippe Mathieu-Daudé         return;
748d7f2e76SPhilippe Mathieu-Daudé     }
758d7f2e76SPhilippe Mathieu-Daudé     balloon_event_fn = NULL;
768d7f2e76SPhilippe Mathieu-Daudé     balloon_stat_fn = NULL;
778d7f2e76SPhilippe Mathieu-Daudé     balloon_opaque = NULL;
788d7f2e76SPhilippe Mathieu-Daudé }
798d7f2e76SPhilippe Mathieu-Daudé 
qmp_query_balloon(Error ** errp)808d7f2e76SPhilippe Mathieu-Daudé BalloonInfo *qmp_query_balloon(Error **errp)
818d7f2e76SPhilippe Mathieu-Daudé {
828d7f2e76SPhilippe Mathieu-Daudé     BalloonInfo *info;
838d7f2e76SPhilippe Mathieu-Daudé 
848d7f2e76SPhilippe Mathieu-Daudé     if (!have_balloon(errp)) {
858d7f2e76SPhilippe Mathieu-Daudé         return NULL;
868d7f2e76SPhilippe Mathieu-Daudé     }
878d7f2e76SPhilippe Mathieu-Daudé 
888d7f2e76SPhilippe Mathieu-Daudé     info = g_malloc0(sizeof(*info));
898d7f2e76SPhilippe Mathieu-Daudé     balloon_stat_fn(balloon_opaque, info);
908d7f2e76SPhilippe Mathieu-Daudé     return info;
918d7f2e76SPhilippe Mathieu-Daudé }
928d7f2e76SPhilippe Mathieu-Daudé 
qmp_balloon(int64_t value,Error ** errp)93eeef44b3SMarkus Armbruster void qmp_balloon(int64_t value, Error **errp)
948d7f2e76SPhilippe Mathieu-Daudé {
958d7f2e76SPhilippe Mathieu-Daudé     if (!have_balloon(errp)) {
968d7f2e76SPhilippe Mathieu-Daudé         return;
978d7f2e76SPhilippe Mathieu-Daudé     }
988d7f2e76SPhilippe Mathieu-Daudé 
99eeef44b3SMarkus Armbruster     if (value <= 0) {
100eeef44b3SMarkus Armbruster         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "value", "a size");
1018d7f2e76SPhilippe Mathieu-Daudé         return;
1028d7f2e76SPhilippe Mathieu-Daudé     }
1038d7f2e76SPhilippe Mathieu-Daudé 
104eeef44b3SMarkus Armbruster     trace_balloon_event(balloon_opaque, value);
105eeef44b3SMarkus Armbruster     balloon_event_fn(balloon_opaque, value);
1068d7f2e76SPhilippe Mathieu-Daudé }
107