]>
Commit | Line | Data |
---|---|---|
04b0de0e WL |
1 | /* |
2 | * Copyright (C) 2014 Citrix Systems UK Ltd. | |
3 | * | |
4 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
5 | * the COPYING file in the top-level directory. | |
6 | * | |
7 | * Contributions after 2012-01-13 are licensed under the terms of the | |
8 | * GNU GPL, version 2 or (at your option) any later version. | |
9 | */ | |
10 | ||
21cbfe5f | 11 | #include "qemu/osdep.h" |
47d17c0a | 12 | #include "qemu/error-report.h" |
0b8fa32f | 13 | #include "qemu/module.h" |
46472d82 | 14 | #include "qapi/error.h" |
e2abfe5e | 15 | #include "hw/xen/xen_native.h" |
2d0ed5e6 | 16 | #include "hw/xen/xen-legacy-backend.h" |
46472d82 | 17 | #include "hw/xen/xen_pt.h" |
8228e353 | 18 | #include "chardev/char.h" |
940e43aa | 19 | #include "qemu/accel.h" |
efd4d93b | 20 | #include "sysemu/cpus.h" |
da278d58 | 21 | #include "sysemu/xen.h" |
54d31236 | 22 | #include "sysemu/runstate.h" |
c4b63b7c | 23 | #include "migration/misc.h" |
84a899de | 24 | #include "migration/global_state.h" |
0dc0389f | 25 | #include "hw/boards.h" |
04b0de0e | 26 | |
8e0ef068 | 27 | bool xen_allowed; |
da278d58 | 28 | |
260cabed PD |
29 | xc_interface *xen_xc; |
30 | xenforeignmemory_handle *xen_fmem; | |
d655f34e | 31 | xendevicemodel_handle *xen_dmod; |
260cabed | 32 | |
ba2a92db | 33 | static void xenstore_record_dm_state(const char *state) |
04b0de0e WL |
34 | { |
35 | char path[50]; | |
36 | ||
04b0de0e | 37 | snprintf(path, sizeof (path), "device-model/%u/state", xen_domid); |
f75e4f22 | 38 | if (!qemu_xen_xs_write(xenstore, XBT_NULL, path, state, strlen(state))) { |
47d17c0a | 39 | error_report("error recording dm state"); |
04b0de0e WL |
40 | exit(1); |
41 | } | |
42 | } | |
43 | ||
44 | ||
538f0497 | 45 | static void xen_change_state_handler(void *opaque, bool running, |
04b0de0e WL |
46 | RunState state) |
47 | { | |
48 | if (running) { | |
49 | /* record state running */ | |
ba2a92db | 50 | xenstore_record_dm_state("running"); |
04b0de0e WL |
51 | } |
52 | } | |
53 | ||
46472d82 PB |
54 | static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp) |
55 | { | |
acd0c941 | 56 | return xen_igd_gfx_pt_enabled(); |
46472d82 PB |
57 | } |
58 | ||
59 | static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp) | |
60 | { | |
acd0c941 | 61 | xen_igd_gfx_pt_set(value, errp); |
46472d82 PB |
62 | } |
63 | ||
4564e63f IJ |
64 | static void xen_setup_post(MachineState *ms, AccelState *accel) |
65 | { | |
66 | int rc; | |
67 | ||
68 | if (xen_domid_restrict) { | |
69 | rc = xen_restrict(xen_domid); | |
70 | if (rc < 0) { | |
71 | perror("xen: failed to restrict"); | |
72 | exit(1); | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
f6a1ef64 | 77 | static int xen_init(MachineState *ms) |
04b0de0e | 78 | { |
0dc0389f IM |
79 | MachineClass *mc = MACHINE_GET_CLASS(ms); |
80 | ||
81daba58 IC |
81 | xen_xc = xc_interface_open(0, 0, 0); |
82 | if (xen_xc == NULL) { | |
96c77dba | 83 | xen_pv_printf(NULL, 0, "can't open xen interface\n"); |
04b0de0e WL |
84 | return -1; |
85 | } | |
e0cb42ae IC |
86 | xen_fmem = xenforeignmemory_open(0, 0); |
87 | if (xen_fmem == NULL) { | |
96c77dba | 88 | xen_pv_printf(NULL, 0, "can't open xen fmem interface\n"); |
e0cb42ae IC |
89 | xc_interface_close(xen_xc); |
90 | return -1; | |
91 | } | |
d655f34e PD |
92 | xen_dmod = xendevicemodel_open(0, 0); |
93 | if (xen_dmod == NULL) { | |
94 | xen_pv_printf(NULL, 0, "can't open xen devicemodel interface\n"); | |
95 | xenforeignmemory_close(xen_fmem); | |
96 | xc_interface_close(xen_xc); | |
97 | return -1; | |
98 | } | |
f75e4f22 DW |
99 | |
100 | /* | |
101 | * The XenStore write would fail when running restricted so don't attempt | |
102 | * it in that case. Toolstacks should instead use QMP to listen for state | |
103 | * changes. | |
104 | */ | |
105 | if (!xen_domid_restrict) { | |
106 | qemu_add_vm_change_state_handler(xen_change_state_handler, NULL); | |
107 | } | |
0dc0389f IM |
108 | /* |
109 | * opt out of system RAM being allocated by generic code | |
110 | */ | |
111 | mc->default_ram_id = NULL; | |
faa4e800 DW |
112 | |
113 | xen_mode = XEN_ATTACH; | |
04b0de0e WL |
114 | return 0; |
115 | } | |
116 | ||
b152b05a EH |
117 | static void xen_accel_class_init(ObjectClass *oc, void *data) |
118 | { | |
119 | AccelClass *ac = ACCEL_CLASS(oc); | |
88cbe073 | 120 | static GlobalProperty compat[] = { |
6c36bddf EH |
121 | { "migration", "store-global-state", "off" }, |
122 | { "migration", "send-configuration", "off" }, | |
123 | { "migration", "send-section-footer", "off" }, | |
88cbe073 | 124 | }; |
ea9ce893 | 125 | |
b152b05a | 126 | ac->name = "Xen"; |
0d15da8e | 127 | ac->init_machine = xen_init; |
4564e63f | 128 | ac->setup_post = xen_setup_post; |
b152b05a | 129 | ac->allowed = &xen_allowed; |
ea9ce893 MAL |
130 | ac->compat_props = g_ptr_array_new(); |
131 | ||
88cbe073 | 132 | compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat)); |
46472d82 PB |
133 | |
134 | object_class_property_add_bool(oc, "igd-passthru", | |
d2623129 | 135 | xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru); |
46472d82 | 136 | object_class_property_set_description(oc, "igd-passthru", |
7eecec7d | 137 | "Set on/off to enable/disable igd passthrou"); |
b152b05a EH |
138 | } |
139 | ||
140 | #define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen") | |
141 | ||
142 | static const TypeInfo xen_accel_type = { | |
143 | .name = TYPE_XEN_ACCEL, | |
144 | .parent = TYPE_ACCEL, | |
145 | .class_init = xen_accel_class_init, | |
146 | }; | |
147 | ||
b86f59c7 CF |
148 | static void xen_accel_ops_class_init(ObjectClass *oc, void *data) |
149 | { | |
150 | AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); | |
151 | ||
152 | ops->create_vcpu_thread = dummy_start_vcpu_thread; | |
153 | } | |
154 | ||
155 | static const TypeInfo xen_accel_ops_type = { | |
156 | .name = ACCEL_OPS_NAME("xen"), | |
157 | ||
158 | .parent = TYPE_ACCEL_OPS, | |
159 | .class_init = xen_accel_ops_class_init, | |
160 | .abstract = true, | |
161 | }; | |
162 | ||
b152b05a EH |
163 | static void xen_type_init(void) |
164 | { | |
165 | type_register_static(&xen_accel_type); | |
b86f59c7 | 166 | type_register_static(&xen_accel_ops_type); |
b152b05a | 167 | } |
b152b05a | 168 | type_init(xen_type_init); |