cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

spice-app.c (7007B)


      1/*
      2 * QEMU external Spice client display driver
      3 *
      4 * Copyright (c) 2018 Marc-André Lureau <marcandre.lureau@redhat.com>
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25#include "qemu/osdep.h"
     26
     27#include <gio/gio.h>
     28
     29#include "ui/console.h"
     30#include "ui/spice-display.h"
     31#include "qemu/config-file.h"
     32#include "qemu/option.h"
     33#include "qemu/cutils.h"
     34#include "qemu/module.h"
     35#include "qapi/error.h"
     36#include "io/channel-command.h"
     37#include "chardev/spice.h"
     38#include "sysemu/sysemu.h"
     39#include "qom/object.h"
     40
     41static const char *tmp_dir;
     42static char *app_dir;
     43static char *sock_path;
     44
     45struct VCChardev {
     46    SpiceChardev parent;
     47};
     48
     49struct VCChardevClass {
     50    ChardevClass parent;
     51    void (*parent_open)(Chardev *chr, ChardevBackend *backend,
     52                        bool *be_opened, Error **errp);
     53};
     54
     55#define TYPE_CHARDEV_VC "chardev-vc"
     56OBJECT_DECLARE_TYPE(VCChardev, VCChardevClass, CHARDEV_VC)
     57
     58static ChardevBackend *
     59chr_spice_backend_new(void)
     60{
     61    ChardevBackend *be = g_new0(ChardevBackend, 1);
     62
     63    be->type = CHARDEV_BACKEND_KIND_SPICEPORT;
     64    be->u.spiceport.data = g_new0(ChardevSpicePort, 1);
     65
     66    return be;
     67}
     68
     69static void vc_chr_open(Chardev *chr,
     70                        ChardevBackend *backend,
     71                        bool *be_opened,
     72                        Error **errp)
     73{
     74    VCChardevClass *vc = CHARDEV_VC_GET_CLASS(chr);
     75    ChardevBackend *be;
     76    const char *fqdn = NULL;
     77
     78    if (strstart(chr->label, "serial", NULL)) {
     79        fqdn = "org.qemu.console.serial.0";
     80    } else if (strstart(chr->label, "parallel", NULL)) {
     81        fqdn = "org.qemu.console.parallel.0";
     82    } else if (strstart(chr->label, "compat_monitor", NULL)) {
     83        fqdn = "org.qemu.monitor.hmp.0";
     84    }
     85
     86    be = chr_spice_backend_new();
     87    be->u.spiceport.data->fqdn = fqdn ?
     88        g_strdup(fqdn) : g_strdup_printf("org.qemu.console.%s", chr->label);
     89    vc->parent_open(chr, be, be_opened, errp);
     90    qapi_free_ChardevBackend(be);
     91}
     92
     93static void vc_chr_set_echo(Chardev *chr, bool echo)
     94{
     95    /* TODO: set echo for frontends QMP and qtest */
     96}
     97
     98static void char_vc_class_init(ObjectClass *oc, void *data)
     99{
    100    VCChardevClass *vc = CHARDEV_VC_CLASS(oc);
    101    ChardevClass *cc = CHARDEV_CLASS(oc);
    102
    103    vc->parent_open = cc->open;
    104
    105    cc->parse = qemu_chr_parse_vc;
    106    cc->open = vc_chr_open;
    107    cc->chr_set_echo = vc_chr_set_echo;
    108}
    109
    110static const TypeInfo char_vc_type_info = {
    111    .name = TYPE_CHARDEV_VC,
    112    .parent = TYPE_CHARDEV_SPICEPORT,
    113    .instance_size = sizeof(VCChardev),
    114    .class_init = char_vc_class_init,
    115    .class_size = sizeof(VCChardevClass),
    116};
    117
    118static void spice_app_atexit(void)
    119{
    120    if (sock_path) {
    121        unlink(sock_path);
    122    }
    123    if (tmp_dir) {
    124        rmdir(tmp_dir);
    125    }
    126    g_free(sock_path);
    127    g_free(app_dir);
    128}
    129
    130static void spice_app_display_early_init(DisplayOptions *opts)
    131{
    132    QemuOpts *qopts;
    133    QemuOptsList *list;
    134    GError *err = NULL;
    135
    136    if (opts->has_full_screen) {
    137        error_report("spice-app full-screen isn't supported yet.");
    138        exit(1);
    139    }
    140    if (opts->has_window_close) {
    141        error_report("spice-app window-close isn't supported yet.");
    142        exit(1);
    143    }
    144
    145    atexit(spice_app_atexit);
    146
    147    if (qemu_name) {
    148        app_dir = g_build_filename(g_get_user_runtime_dir(),
    149                                   "qemu", qemu_name, NULL);
    150        if (g_mkdir_with_parents(app_dir, S_IRWXU) < -1) {
    151            error_report("Failed to create directory %s: %s",
    152                         app_dir, strerror(errno));
    153            exit(1);
    154        }
    155    } else {
    156        app_dir = g_dir_make_tmp(NULL, &err);
    157        tmp_dir = app_dir;
    158        if (err) {
    159            error_report("Failed to create temporary directory: %s",
    160                         err->message);
    161            exit(1);
    162        }
    163    }
    164    list = qemu_find_opts("spice");
    165    if (list == NULL) {
    166        error_report("spice-app missing spice support");
    167        exit(1);
    168    }
    169
    170    type_register(&char_vc_type_info);
    171
    172    sock_path = g_strjoin("", app_dir, "/", "spice.sock", NULL);
    173    qopts = qemu_opts_create(list, NULL, 0, &error_abort);
    174    qemu_opt_set(qopts, "disable-ticketing", "on", &error_abort);
    175    qemu_opt_set(qopts, "unix", "on", &error_abort);
    176    qemu_opt_set(qopts, "addr", sock_path, &error_abort);
    177    qemu_opt_set(qopts, "image-compression", "off", &error_abort);
    178    qemu_opt_set(qopts, "streaming-video", "off", &error_abort);
    179#ifdef HAVE_SPICE_GL
    180    qemu_opt_set(qopts, "gl", opts->has_gl ? "on" : "off", &error_abort);
    181    display_opengl = opts->has_gl;
    182#endif
    183}
    184
    185static void spice_app_display_init(DisplayState *ds, DisplayOptions *opts)
    186{
    187    ChardevBackend *be = chr_spice_backend_new();
    188    QemuOpts *qopts;
    189    GError *err = NULL;
    190    gchar *uri;
    191
    192    be->u.spiceport.data->fqdn = g_strdup("org.qemu.monitor.qmp.0");
    193    qemu_chardev_new("org.qemu.monitor.qmp", TYPE_CHARDEV_SPICEPORT,
    194                     be, NULL, &error_abort);
    195    qopts = qemu_opts_create(qemu_find_opts("mon"),
    196                             NULL, 0, &error_fatal);
    197    qemu_opt_set(qopts, "chardev", "org.qemu.monitor.qmp", &error_abort);
    198    qemu_opt_set(qopts, "mode", "control", &error_abort);
    199
    200    qapi_free_ChardevBackend(be);
    201    uri = g_strjoin("", "spice+unix://", app_dir, "/", "spice.sock", NULL);
    202    info_report("Launching display with URI: %s", uri);
    203    g_app_info_launch_default_for_uri(uri, NULL, &err);
    204    if (err) {
    205        error_report("Failed to launch %s URI: %s", uri, err->message);
    206        error_report("You need a capable Spice client, "
    207                     "such as virt-viewer 8.0");
    208        exit(1);
    209    }
    210    g_free(uri);
    211}
    212
    213static QemuDisplay qemu_display_spice_app = {
    214    .type       = DISPLAY_TYPE_SPICE_APP,
    215    .early_init = spice_app_display_early_init,
    216    .init       = spice_app_display_init,
    217};
    218
    219static void register_spice_app(void)
    220{
    221    qemu_display_register(&qemu_display_spice_app);
    222}
    223
    224type_init(register_spice_app);
    225
    226module_dep("ui-spice-core");
    227module_dep("chardev-spice");