diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-06-12 23:06:22 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-06-12 23:06:22 +0100 |
| commit | 7d3660e79830a069f1848bb4fa1cdf8f666424fb (patch) | |
| tree | 5651ddf02414086c31d0bfca7713e1800d4f0fc8 /accel/xen/xen-all.c | |
| parent | 9e3903136d9acde2fb2dd9e967ba928050a6cb4a (diff) | |
| parent | 3575b0aea983ad57804c9af739ed8ff7bc168393 (diff) | |
| download | focaccia-qemu-7d3660e79830a069f1848bb4fa1cdf8f666424fb.tar.gz focaccia-qemu-7d3660e79830a069f1848bb4fa1cdf8f666424fb.zip | |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* Miscellaneous fixes and feature enablement (many) * SEV refactoring (David) * Hyper-V initial support (Jon) * i386 TCG fixes (x87 and SSE, Joseph) * vmport cleanup and improvements (Philippe, Liran) * Use-after-free with vCPU hot-unplug (Nengyuan) * run-coverity-scan improvements (myself) * Record/replay fixes (Pavel) * -machine kernel_irqchip=split improvements for INTx (Peter) * Code cleanups (Philippe) * Crash and security fixes (PJP) * HVF cleanups (Roman) # gpg: Signature made Fri 12 Jun 2020 16:57:04 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (116 commits) target/i386: Remove obsolete TODO file stubs: move Xen stubs to accel/ replay: fix replay shutdown for console mode exec/cpu-common: Move MUSB specific typedefs to 'hw/usb/hcd-musb.h' hw/usb: Move device-specific declarations to new 'hcd-musb.h' header exec/memory: Remove unused MemoryRegionMmio type checkpatch: reversed logic with acpi test checks target/i386: sev: Unify SEVState and SevGuestState target/i386: sev: Remove redundant handle field target/i386: sev: Remove redundant policy field target/i386: sev: Remove redundant cbitpos and reduced_phys_bits fields target/i386: sev: Partial cleanup to sev_state global target/i386: sev: Embed SEVState in SevGuestState target/i386: sev: Rename QSevGuestInfo target/i386: sev: Move local structure definitions into .c file target/i386: sev: Remove unused QSevGuestInfoClass xen: fix build without pci passthrough i386: hvf: Drop HVFX86EmulatorState i386: hvf: Move mmio_buf into CPUX86State i386: hvf: Move lazy_flags into CPUX86State ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # hw/i386/acpi-build.c
Diffstat (limited to 'accel/xen/xen-all.c')
| -rw-r--r-- | accel/xen/xen-all.c | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c new file mode 100644 index 0000000000..0c24d4b191 --- /dev/null +++ b/accel/xen/xen-all.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2014 Citrix Systems UK Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qemu/module.h" +#include "qapi/error.h" +#include "hw/xen/xen-legacy-backend.h" +#include "hw/xen/xen_pt.h" +#include "chardev/char.h" +#include "sysemu/accel.h" +#include "sysemu/xen.h" +#include "sysemu/runstate.h" +#include "migration/misc.h" +#include "migration/global_state.h" +#include "hw/boards.h" + +//#define DEBUG_XEN + +#ifdef DEBUG_XEN +#define DPRINTF(fmt, ...) \ + do { fprintf(stderr, "xen: " fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +static bool xen_allowed; + +bool xen_enabled(void) +{ + return xen_allowed; +} + +xc_interface *xen_xc; +xenforeignmemory_handle *xen_fmem; +xendevicemodel_handle *xen_dmod; + +static int store_dev_info(int domid, Chardev *cs, const char *string) +{ + struct xs_handle *xs = NULL; + char *path = NULL; + char *newpath = NULL; + char *pts = NULL; + int ret = -1; + + /* Only continue if we're talking to a pty. */ + if (!CHARDEV_IS_PTY(cs)) { + return 0; + } + pts = cs->filename + 4; + + /* We now have everything we need to set the xenstore entry. */ + xs = xs_open(0); + if (xs == NULL) { + fprintf(stderr, "Could not contact XenStore\n"); + goto out; + } + + path = xs_get_domain_path(xs, domid); + if (path == NULL) { + fprintf(stderr, "xs_get_domain_path() error\n"); + goto out; + } + newpath = realloc(path, (strlen(path) + strlen(string) + + strlen("/tty") + 1)); + if (newpath == NULL) { + fprintf(stderr, "realloc error\n"); + goto out; + } + path = newpath; + + strcat(path, string); + strcat(path, "/tty"); + if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) { + fprintf(stderr, "xs_write for '%s' fail", string); + goto out; + } + ret = 0; + +out: + free(path); + xs_close(xs); + + return ret; +} + +void xenstore_store_pv_console_info(int i, Chardev *chr) +{ + if (i == 0) { + store_dev_info(xen_domid, chr, "/console"); + } else { + char buf[32]; + snprintf(buf, sizeof(buf), "/device/console/%d", i); + store_dev_info(xen_domid, chr, buf); + } +} + + +static void xenstore_record_dm_state(struct xs_handle *xs, const char *state) +{ + char path[50]; + + if (xs == NULL) { + error_report("xenstore connection not initialized"); + exit(1); + } + + snprintf(path, sizeof (path), "device-model/%u/state", xen_domid); + /* + * This call may fail when running restricted so don't make it fatal in + * that case. Toolstacks should instead use QMP to listen for state changes. + */ + if (!xs_write(xs, XBT_NULL, path, state, strlen(state)) && + !xen_domid_restrict) { + error_report("error recording dm state"); + exit(1); + } +} + + +static void xen_change_state_handler(void *opaque, int running, + RunState state) +{ + if (running) { + /* record state running */ + xenstore_record_dm_state(xenstore, "running"); + } +} + +static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp) +{ + return xen_igd_gfx_pt_enabled(); +} + +static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp) +{ + xen_igd_gfx_pt_set(value, errp); +} + +static void xen_setup_post(MachineState *ms, AccelState *accel) +{ + int rc; + + if (xen_domid_restrict) { + rc = xen_restrict(xen_domid); + if (rc < 0) { + perror("xen: failed to restrict"); + exit(1); + } + } +} + +static int xen_init(MachineState *ms) +{ + MachineClass *mc = MACHINE_GET_CLASS(ms); + + xen_xc = xc_interface_open(0, 0, 0); + if (xen_xc == NULL) { + xen_pv_printf(NULL, 0, "can't open xen interface\n"); + return -1; + } + xen_fmem = xenforeignmemory_open(0, 0); + if (xen_fmem == NULL) { + xen_pv_printf(NULL, 0, "can't open xen fmem interface\n"); + xc_interface_close(xen_xc); + return -1; + } + xen_dmod = xendevicemodel_open(0, 0); + if (xen_dmod == NULL) { + xen_pv_printf(NULL, 0, "can't open xen devicemodel interface\n"); + xenforeignmemory_close(xen_fmem); + xc_interface_close(xen_xc); + return -1; + } + qemu_add_vm_change_state_handler(xen_change_state_handler, NULL); + /* + * opt out of system RAM being allocated by generic code + */ + mc->default_ram_id = NULL; + return 0; +} + +static void xen_accel_class_init(ObjectClass *oc, void *data) +{ + AccelClass *ac = ACCEL_CLASS(oc); + static GlobalProperty compat[] = { + { "migration", "store-global-state", "off" }, + { "migration", "send-configuration", "off" }, + { "migration", "send-section-footer", "off" }, + }; + + ac->name = "Xen"; + ac->init_machine = xen_init; + ac->setup_post = xen_setup_post; + ac->allowed = &xen_allowed; + ac->compat_props = g_ptr_array_new(); + + compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat)); + + object_class_property_add_bool(oc, "igd-passthru", + xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru); + object_class_property_set_description(oc, "igd-passthru", + "Set on/off to enable/disable igd passthrou"); +} + +#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen") + +static const TypeInfo xen_accel_type = { + .name = TYPE_XEN_ACCEL, + .parent = TYPE_ACCEL, + .class_init = xen_accel_class_init, +}; + +static void xen_type_init(void) +{ + type_register_static(&xen_accel_type); +} + +type_init(xen_type_init); |