qxl.c 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361
  1. /*
  2. * Copyright (C) 2010 Red Hat, Inc.
  3. *
  4. * written by Yaniv Kamay, Izik Eidus, Gerd Hoffmann
  5. * maintained by Gerd Hoffmann <kraxel@redhat.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 or
  10. * (at your option) version 3 of the License.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include <zlib.h>
  21. #include <stdint.h>
  22. #include "qemu-common.h"
  23. #include "qemu/timer.h"
  24. #include "qemu/queue.h"
  25. #include "qemu/atomic.h"
  26. #include "monitor/monitor.h"
  27. #include "sysemu/sysemu.h"
  28. #include "trace.h"
  29. #include "qxl.h"
  30. /*
  31. * NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
  32. * such can be changed by the guest, so to avoid a guest trigerrable
  33. * abort we just qxl_set_guest_bug and set the return to NULL. Still
  34. * it may happen as a result of emulator bug as well.
  35. */
  36. #undef SPICE_RING_PROD_ITEM
  37. #define SPICE_RING_PROD_ITEM(qxl, r, ret) { \
  38. uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \
  39. if (prod >= ARRAY_SIZE((r)->items)) { \
  40. qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \
  41. "%u >= %zu", prod, ARRAY_SIZE((r)->items)); \
  42. ret = NULL; \
  43. } else { \
  44. ret = &(r)->items[prod].el; \
  45. } \
  46. }
  47. #undef SPICE_RING_CONS_ITEM
  48. #define SPICE_RING_CONS_ITEM(qxl, r, ret) { \
  49. uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \
  50. if (cons >= ARRAY_SIZE((r)->items)) { \
  51. qxl_set_guest_bug(qxl, "SPICE_RING_CONS_ITEM indices mismatch " \
  52. "%u >= %zu", cons, ARRAY_SIZE((r)->items)); \
  53. ret = NULL; \
  54. } else { \
  55. ret = &(r)->items[cons].el; \
  56. } \
  57. }
  58. #undef ALIGN
  59. #define ALIGN(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
  60. #define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9"
  61. #define QXL_MODE(_x, _y, _b, _o) \
  62. { .x_res = _x, \
  63. .y_res = _y, \
  64. .bits = _b, \
  65. .stride = (_x) * (_b) / 8, \
  66. .x_mili = PIXEL_SIZE * (_x), \
  67. .y_mili = PIXEL_SIZE * (_y), \
  68. .orientation = _o, \
  69. }
  70. #define QXL_MODE_16_32(x_res, y_res, orientation) \
  71. QXL_MODE(x_res, y_res, 16, orientation), \
  72. QXL_MODE(x_res, y_res, 32, orientation)
  73. #define QXL_MODE_EX(x_res, y_res) \
  74. QXL_MODE_16_32(x_res, y_res, 0), \
  75. QXL_MODE_16_32(x_res, y_res, 1)
  76. static QXLMode qxl_modes[] = {
  77. QXL_MODE_EX(640, 480),
  78. QXL_MODE_EX(800, 480),
  79. QXL_MODE_EX(800, 600),
  80. QXL_MODE_EX(832, 624),
  81. QXL_MODE_EX(960, 640),
  82. QXL_MODE_EX(1024, 600),
  83. QXL_MODE_EX(1024, 768),
  84. QXL_MODE_EX(1152, 864),
  85. QXL_MODE_EX(1152, 870),
  86. QXL_MODE_EX(1280, 720),
  87. QXL_MODE_EX(1280, 760),
  88. QXL_MODE_EX(1280, 768),
  89. QXL_MODE_EX(1280, 800),
  90. QXL_MODE_EX(1280, 960),
  91. QXL_MODE_EX(1280, 1024),
  92. QXL_MODE_EX(1360, 768),
  93. QXL_MODE_EX(1366, 768),
  94. QXL_MODE_EX(1400, 1050),
  95. QXL_MODE_EX(1440, 900),
  96. QXL_MODE_EX(1600, 900),
  97. QXL_MODE_EX(1600, 1200),
  98. QXL_MODE_EX(1680, 1050),
  99. QXL_MODE_EX(1920, 1080),
  100. /* these modes need more than 8 MB video memory */
  101. QXL_MODE_EX(1920, 1200),
  102. QXL_MODE_EX(1920, 1440),
  103. QXL_MODE_EX(2000, 2000),
  104. QXL_MODE_EX(2048, 1536),
  105. QXL_MODE_EX(2048, 2048),
  106. QXL_MODE_EX(2560, 1440),
  107. QXL_MODE_EX(2560, 1600),
  108. /* these modes need more than 16 MB video memory */
  109. QXL_MODE_EX(2560, 2048),
  110. QXL_MODE_EX(2800, 2100),
  111. QXL_MODE_EX(3200, 2400),
  112. QXL_MODE_EX(3840, 2160), /* 4k mainstream */
  113. QXL_MODE_EX(4096, 2160), /* 4k */
  114. QXL_MODE_EX(7680, 4320), /* 8k mainstream */
  115. QXL_MODE_EX(8192, 4320), /* 8k */
  116. };
  117. static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
  118. static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
  119. static void qxl_reset_memslots(PCIQXLDevice *d);
  120. static void qxl_reset_surfaces(PCIQXLDevice *d);
  121. static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
  122. void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
  123. {
  124. trace_qxl_set_guest_bug(qxl->id);
  125. qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
  126. qxl->guest_bug = 1;
  127. if (qxl->guestdebug) {
  128. va_list ap;
  129. va_start(ap, msg);
  130. fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
  131. vfprintf(stderr, msg, ap);
  132. fprintf(stderr, "\n");
  133. va_end(ap);
  134. }
  135. }
  136. static void qxl_clear_guest_bug(PCIQXLDevice *qxl)
  137. {
  138. qxl->guest_bug = 0;
  139. }
  140. void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
  141. struct QXLRect *area, struct QXLRect *dirty_rects,
  142. uint32_t num_dirty_rects,
  143. uint32_t clear_dirty_region,
  144. qxl_async_io async, struct QXLCookie *cookie)
  145. {
  146. trace_qxl_spice_update_area(qxl->id, surface_id, area->left, area->right,
  147. area->top, area->bottom);
  148. trace_qxl_spice_update_area_rest(qxl->id, num_dirty_rects,
  149. clear_dirty_region);
  150. if (async == QXL_SYNC) {
  151. spice_qxl_update_area(&qxl->ssd.qxl, surface_id, area,
  152. dirty_rects, num_dirty_rects, clear_dirty_region);
  153. } else {
  154. assert(cookie != NULL);
  155. spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,
  156. clear_dirty_region, (uintptr_t)cookie);
  157. }
  158. }
  159. static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
  160. uint32_t id)
  161. {
  162. trace_qxl_spice_destroy_surface_wait_complete(qxl->id, id);
  163. qemu_mutex_lock(&qxl->track_lock);
  164. qxl->guest_surfaces.cmds[id] = 0;
  165. qxl->guest_surfaces.count--;
  166. qemu_mutex_unlock(&qxl->track_lock);
  167. }
  168. static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
  169. qxl_async_io async)
  170. {
  171. QXLCookie *cookie;
  172. trace_qxl_spice_destroy_surface_wait(qxl->id, id, async);
  173. if (async) {
  174. cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
  175. QXL_IO_DESTROY_SURFACE_ASYNC);
  176. cookie->u.surface_id = id;
  177. spice_qxl_destroy_surface_async(&qxl->ssd.qxl, id, (uintptr_t)cookie);
  178. } else {
  179. spice_qxl_destroy_surface_wait(&qxl->ssd.qxl, id);
  180. qxl_spice_destroy_surface_wait_complete(qxl, id);
  181. }
  182. }
  183. static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
  184. {
  185. trace_qxl_spice_flush_surfaces_async(qxl->id, qxl->guest_surfaces.count,
  186. qxl->num_free_res);
  187. spice_qxl_flush_surfaces_async(&qxl->ssd.qxl,
  188. (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
  189. QXL_IO_FLUSH_SURFACES_ASYNC));
  190. }
  191. void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
  192. uint32_t count)
  193. {
  194. trace_qxl_spice_loadvm_commands(qxl->id, ext, count);
  195. spice_qxl_loadvm_commands(&qxl->ssd.qxl, ext, count);
  196. }
  197. void qxl_spice_oom(PCIQXLDevice *qxl)
  198. {
  199. trace_qxl_spice_oom(qxl->id);
  200. spice_qxl_oom(&qxl->ssd.qxl);
  201. }
  202. void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
  203. {
  204. trace_qxl_spice_reset_memslots(qxl->id);
  205. spice_qxl_reset_memslots(&qxl->ssd.qxl);
  206. }
  207. static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
  208. {
  209. trace_qxl_spice_destroy_surfaces_complete(qxl->id);
  210. qemu_mutex_lock(&qxl->track_lock);
  211. memset(qxl->guest_surfaces.cmds, 0,
  212. sizeof(qxl->guest_surfaces.cmds[0]) * qxl->ssd.num_surfaces);
  213. qxl->guest_surfaces.count = 0;
  214. qemu_mutex_unlock(&qxl->track_lock);
  215. }
  216. static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
  217. {
  218. trace_qxl_spice_destroy_surfaces(qxl->id, async);
  219. if (async) {
  220. spice_qxl_destroy_surfaces_async(&qxl->ssd.qxl,
  221. (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
  222. QXL_IO_DESTROY_ALL_SURFACES_ASYNC));
  223. } else {
  224. spice_qxl_destroy_surfaces(&qxl->ssd.qxl);
  225. qxl_spice_destroy_surfaces_complete(qxl);
  226. }
  227. }
  228. static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
  229. {
  230. trace_qxl_spice_monitors_config(qxl->id);
  231. if (replay) {
  232. /*
  233. * don't use QXL_COOKIE_TYPE_IO:
  234. * - we are not running yet (post_load), we will assert
  235. * in send_events
  236. * - this is not a guest io, but a reply, so async_io isn't set.
  237. */
  238. spice_qxl_monitors_config_async(&qxl->ssd.qxl,
  239. qxl->guest_monitors_config,
  240. MEMSLOT_GROUP_GUEST,
  241. (uintptr_t)qxl_cookie_new(
  242. QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG,
  243. 0));
  244. } else {
  245. qxl->guest_monitors_config = qxl->ram->monitors_config;
  246. spice_qxl_monitors_config_async(&qxl->ssd.qxl,
  247. qxl->ram->monitors_config,
  248. MEMSLOT_GROUP_GUEST,
  249. (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
  250. QXL_IO_MONITORS_CONFIG_ASYNC));
  251. }
  252. }
  253. void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
  254. {
  255. trace_qxl_spice_reset_image_cache(qxl->id);
  256. spice_qxl_reset_image_cache(&qxl->ssd.qxl);
  257. }
  258. void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
  259. {
  260. trace_qxl_spice_reset_cursor(qxl->id);
  261. spice_qxl_reset_cursor(&qxl->ssd.qxl);
  262. qemu_mutex_lock(&qxl->track_lock);
  263. qxl->guest_cursor = 0;
  264. qemu_mutex_unlock(&qxl->track_lock);
  265. if (qxl->ssd.cursor) {
  266. cursor_put(qxl->ssd.cursor);
  267. }
  268. qxl->ssd.cursor = cursor_builtin_hidden();
  269. }
  270. static inline uint32_t msb_mask(uint32_t val)
  271. {
  272. uint32_t mask;
  273. do {
  274. mask = ~(val - 1) & val;
  275. val &= ~mask;
  276. } while (mask < val);
  277. return mask;
  278. }
  279. static ram_addr_t qxl_rom_size(void)
  280. {
  281. uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) +
  282. sizeof(qxl_modes);
  283. uint32_t rom_size = 8192; /* two pages */
  284. QEMU_BUILD_BUG_ON(required_rom_size > rom_size);
  285. return rom_size;
  286. }
  287. static void init_qxl_rom(PCIQXLDevice *d)
  288. {
  289. QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
  290. QXLModes *modes = (QXLModes *)(rom + 1);
  291. uint32_t ram_header_size;
  292. uint32_t surface0_area_size;
  293. uint32_t num_pages;
  294. uint32_t fb;
  295. int i, n;
  296. memset(rom, 0, d->rom_size);
  297. rom->magic = cpu_to_le32(QXL_ROM_MAGIC);
  298. rom->id = cpu_to_le32(d->id);
  299. rom->log_level = cpu_to_le32(d->guestdebug);
  300. rom->modes_offset = cpu_to_le32(sizeof(QXLRom));
  301. rom->slot_gen_bits = MEMSLOT_GENERATION_BITS;
  302. rom->slot_id_bits = MEMSLOT_SLOT_BITS;
  303. rom->slots_start = 1;
  304. rom->slots_end = NUM_MEMSLOTS - 1;
  305. rom->n_surfaces = cpu_to_le32(d->ssd.num_surfaces);
  306. for (i = 0, n = 0; i < ARRAY_SIZE(qxl_modes); i++) {
  307. fb = qxl_modes[i].y_res * qxl_modes[i].stride;
  308. if (fb > d->vgamem_size) {
  309. continue;
  310. }
  311. modes->modes[n].id = cpu_to_le32(i);
  312. modes->modes[n].x_res = cpu_to_le32(qxl_modes[i].x_res);
  313. modes->modes[n].y_res = cpu_to_le32(qxl_modes[i].y_res);
  314. modes->modes[n].bits = cpu_to_le32(qxl_modes[i].bits);
  315. modes->modes[n].stride = cpu_to_le32(qxl_modes[i].stride);
  316. modes->modes[n].x_mili = cpu_to_le32(qxl_modes[i].x_mili);
  317. modes->modes[n].y_mili = cpu_to_le32(qxl_modes[i].y_mili);
  318. modes->modes[n].orientation = cpu_to_le32(qxl_modes[i].orientation);
  319. n++;
  320. }
  321. modes->n_modes = cpu_to_le32(n);
  322. ram_header_size = ALIGN(sizeof(QXLRam), 4096);
  323. surface0_area_size = ALIGN(d->vgamem_size, 4096);
  324. num_pages = d->vga.vram_size;
  325. num_pages -= ram_header_size;
  326. num_pages -= surface0_area_size;
  327. num_pages = num_pages / QXL_PAGE_SIZE;
  328. rom->draw_area_offset = cpu_to_le32(0);
  329. rom->surface0_area_size = cpu_to_le32(surface0_area_size);
  330. rom->pages_offset = cpu_to_le32(surface0_area_size);
  331. rom->num_pages = cpu_to_le32(num_pages);
  332. rom->ram_header_offset = cpu_to_le32(d->vga.vram_size - ram_header_size);
  333. d->shadow_rom = *rom;
  334. d->rom = rom;
  335. d->modes = modes;
  336. }
  337. static void init_qxl_ram(PCIQXLDevice *d)
  338. {
  339. uint8_t *buf;
  340. uint64_t *item;
  341. buf = d->vga.vram_ptr;
  342. d->ram = (QXLRam *)(buf + le32_to_cpu(d->shadow_rom.ram_header_offset));
  343. d->ram->magic = cpu_to_le32(QXL_RAM_MAGIC);
  344. d->ram->int_pending = cpu_to_le32(0);
  345. d->ram->int_mask = cpu_to_le32(0);
  346. d->ram->update_surface = 0;
  347. d->ram->monitors_config = 0;
  348. SPICE_RING_INIT(&d->ram->cmd_ring);
  349. SPICE_RING_INIT(&d->ram->cursor_ring);
  350. SPICE_RING_INIT(&d->ram->release_ring);
  351. SPICE_RING_PROD_ITEM(d, &d->ram->release_ring, item);
  352. assert(item);
  353. *item = 0;
  354. qxl_ring_set_dirty(d);
  355. }
  356. /* can be called from spice server thread context */
  357. static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
  358. {
  359. memory_region_set_dirty(mr, addr, end - addr);
  360. }
  361. static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
  362. {
  363. qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
  364. }
  365. /* called from spice server thread context only */
  366. static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
  367. {
  368. void *base = qxl->vga.vram_ptr;
  369. intptr_t offset;
  370. offset = ptr - base;
  371. assert(offset < qxl->vga.vram_size);
  372. qxl_set_dirty(&qxl->vga.vram, offset, offset + 3);
  373. }
  374. /* can be called from spice server thread context */
  375. static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
  376. {
  377. ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
  378. ram_addr_t end = qxl->vga.vram_size;
  379. qxl_set_dirty(&qxl->vga.vram, addr, end);
  380. }
  381. /*
  382. * keep track of some command state, for savevm/loadvm.
  383. * called from spice server thread context only
  384. */
  385. static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
  386. {
  387. switch (le32_to_cpu(ext->cmd.type)) {
  388. case QXL_CMD_SURFACE:
  389. {
  390. QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
  391. if (!cmd) {
  392. return 1;
  393. }
  394. uint32_t id = le32_to_cpu(cmd->surface_id);
  395. if (id >= qxl->ssd.num_surfaces) {
  396. qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE id %d >= %d", id,
  397. qxl->ssd.num_surfaces);
  398. return 1;
  399. }
  400. if (cmd->type == QXL_SURFACE_CMD_CREATE &&
  401. (cmd->u.surface_create.stride & 0x03) != 0) {
  402. qxl_set_guest_bug(qxl, "QXL_CMD_SURFACE stride = %d %% 4 != 0\n",
  403. cmd->u.surface_create.stride);
  404. return 1;
  405. }
  406. qemu_mutex_lock(&qxl->track_lock);
  407. if (cmd->type == QXL_SURFACE_CMD_CREATE) {
  408. qxl->guest_surfaces.cmds[id] = ext->cmd.data;
  409. qxl->guest_surfaces.count++;
  410. if (qxl->guest_surfaces.max < qxl->guest_surfaces.count)
  411. qxl->guest_surfaces.max = qxl->guest_surfaces.count;
  412. }
  413. if (cmd->type == QXL_SURFACE_CMD_DESTROY) {
  414. qxl->guest_surfaces.cmds[id] = 0;
  415. qxl->guest_surfaces.count--;
  416. }
  417. qemu_mutex_unlock(&qxl->track_lock);
  418. break;
  419. }
  420. case QXL_CMD_CURSOR:
  421. {
  422. QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
  423. if (!cmd) {
  424. return 1;
  425. }
  426. if (cmd->type == QXL_CURSOR_SET) {
  427. qemu_mutex_lock(&qxl->track_lock);
  428. qxl->guest_cursor = ext->cmd.data;
  429. qemu_mutex_unlock(&qxl->track_lock);
  430. }
  431. break;
  432. }
  433. }
  434. return 0;
  435. }
  436. /* spice display interface callbacks */
  437. static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
  438. {
  439. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  440. trace_qxl_interface_attach_worker(qxl->id);
  441. qxl->ssd.worker = qxl_worker;
  442. }
  443. static void interface_set_compression_level(QXLInstance *sin, int level)
  444. {
  445. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  446. trace_qxl_interface_set_compression_level(qxl->id, level);
  447. qxl->shadow_rom.compression_level = cpu_to_le32(level);
  448. qxl->rom->compression_level = cpu_to_le32(level);
  449. qxl_rom_set_dirty(qxl);
  450. }
  451. static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
  452. {
  453. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  454. trace_qxl_interface_set_mm_time(qxl->id, mm_time);
  455. qxl->shadow_rom.mm_clock = cpu_to_le32(mm_time);
  456. qxl->rom->mm_clock = cpu_to_le32(mm_time);
  457. qxl_rom_set_dirty(qxl);
  458. }
  459. static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
  460. {
  461. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  462. trace_qxl_interface_get_init_info(qxl->id);
  463. info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
  464. info->memslot_id_bits = MEMSLOT_SLOT_BITS;
  465. info->num_memslots = NUM_MEMSLOTS;
  466. info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
  467. info->internal_groupslot_id = 0;
  468. info->qxl_ram_size =
  469. le32_to_cpu(qxl->shadow_rom.num_pages) << QXL_PAGE_BITS;
  470. info->n_surfaces = qxl->ssd.num_surfaces;
  471. }
  472. static const char *qxl_mode_to_string(int mode)
  473. {
  474. switch (mode) {
  475. case QXL_MODE_COMPAT:
  476. return "compat";
  477. case QXL_MODE_NATIVE:
  478. return "native";
  479. case QXL_MODE_UNDEFINED:
  480. return "undefined";
  481. case QXL_MODE_VGA:
  482. return "vga";
  483. }
  484. return "INVALID";
  485. }
  486. static const char *io_port_to_string(uint32_t io_port)
  487. {
  488. if (io_port >= QXL_IO_RANGE_SIZE) {
  489. return "out of range";
  490. }
  491. static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {
  492. [QXL_IO_NOTIFY_CMD] = "QXL_IO_NOTIFY_CMD",
  493. [QXL_IO_NOTIFY_CURSOR] = "QXL_IO_NOTIFY_CURSOR",
  494. [QXL_IO_UPDATE_AREA] = "QXL_IO_UPDATE_AREA",
  495. [QXL_IO_UPDATE_IRQ] = "QXL_IO_UPDATE_IRQ",
  496. [QXL_IO_NOTIFY_OOM] = "QXL_IO_NOTIFY_OOM",
  497. [QXL_IO_RESET] = "QXL_IO_RESET",
  498. [QXL_IO_SET_MODE] = "QXL_IO_SET_MODE",
  499. [QXL_IO_LOG] = "QXL_IO_LOG",
  500. [QXL_IO_MEMSLOT_ADD] = "QXL_IO_MEMSLOT_ADD",
  501. [QXL_IO_MEMSLOT_DEL] = "QXL_IO_MEMSLOT_DEL",
  502. [QXL_IO_DETACH_PRIMARY] = "QXL_IO_DETACH_PRIMARY",
  503. [QXL_IO_ATTACH_PRIMARY] = "QXL_IO_ATTACH_PRIMARY",
  504. [QXL_IO_CREATE_PRIMARY] = "QXL_IO_CREATE_PRIMARY",
  505. [QXL_IO_DESTROY_PRIMARY] = "QXL_IO_DESTROY_PRIMARY",
  506. [QXL_IO_DESTROY_SURFACE_WAIT] = "QXL_IO_DESTROY_SURFACE_WAIT",
  507. [QXL_IO_DESTROY_ALL_SURFACES] = "QXL_IO_DESTROY_ALL_SURFACES",
  508. [QXL_IO_UPDATE_AREA_ASYNC] = "QXL_IO_UPDATE_AREA_ASYNC",
  509. [QXL_IO_MEMSLOT_ADD_ASYNC] = "QXL_IO_MEMSLOT_ADD_ASYNC",
  510. [QXL_IO_CREATE_PRIMARY_ASYNC] = "QXL_IO_CREATE_PRIMARY_ASYNC",
  511. [QXL_IO_DESTROY_PRIMARY_ASYNC] = "QXL_IO_DESTROY_PRIMARY_ASYNC",
  512. [QXL_IO_DESTROY_SURFACE_ASYNC] = "QXL_IO_DESTROY_SURFACE_ASYNC",
  513. [QXL_IO_DESTROY_ALL_SURFACES_ASYNC]
  514. = "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
  515. [QXL_IO_FLUSH_SURFACES_ASYNC] = "QXL_IO_FLUSH_SURFACES_ASYNC",
  516. [QXL_IO_FLUSH_RELEASE] = "QXL_IO_FLUSH_RELEASE",
  517. [QXL_IO_MONITORS_CONFIG_ASYNC] = "QXL_IO_MONITORS_CONFIG_ASYNC",
  518. };
  519. return io_port_to_string[io_port];
  520. }
  521. /* called from spice server thread context only */
  522. static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
  523. {
  524. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  525. SimpleSpiceUpdate *update;
  526. QXLCommandRing *ring;
  527. QXLCommand *cmd;
  528. int notify, ret;
  529. trace_qxl_ring_command_check(qxl->id, qxl_mode_to_string(qxl->mode));
  530. switch (qxl->mode) {
  531. case QXL_MODE_VGA:
  532. ret = false;
  533. qemu_mutex_lock(&qxl->ssd.lock);
  534. update = QTAILQ_FIRST(&qxl->ssd.updates);
  535. if (update != NULL) {
  536. QTAILQ_REMOVE(&qxl->ssd.updates, update, next);
  537. *ext = update->ext;
  538. ret = true;
  539. }
  540. qemu_mutex_unlock(&qxl->ssd.lock);
  541. if (ret) {
  542. trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
  543. qxl_log_command(qxl, "vga", ext);
  544. }
  545. return ret;
  546. case QXL_MODE_COMPAT:
  547. case QXL_MODE_NATIVE:
  548. case QXL_MODE_UNDEFINED:
  549. ring = &qxl->ram->cmd_ring;
  550. if (qxl->guest_bug || SPICE_RING_IS_EMPTY(ring)) {
  551. return false;
  552. }
  553. SPICE_RING_CONS_ITEM(qxl, ring, cmd);
  554. if (!cmd) {
  555. return false;
  556. }
  557. ext->cmd = *cmd;
  558. ext->group_id = MEMSLOT_GROUP_GUEST;
  559. ext->flags = qxl->cmdflags;
  560. SPICE_RING_POP(ring, notify);
  561. qxl_ring_set_dirty(qxl);
  562. if (notify) {
  563. qxl_send_events(qxl, QXL_INTERRUPT_DISPLAY);
  564. }
  565. qxl->guest_primary.commands++;
  566. qxl_track_command(qxl, ext);
  567. qxl_log_command(qxl, "cmd", ext);
  568. trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
  569. return true;
  570. default:
  571. return false;
  572. }
  573. }
  574. /* called from spice server thread context only */
  575. static int interface_req_cmd_notification(QXLInstance *sin)
  576. {
  577. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  578. int wait = 1;
  579. trace_qxl_ring_command_req_notification(qxl->id);
  580. switch (qxl->mode) {
  581. case QXL_MODE_COMPAT:
  582. case QXL_MODE_NATIVE:
  583. case QXL_MODE_UNDEFINED:
  584. SPICE_RING_CONS_WAIT(&qxl->ram->cmd_ring, wait);
  585. qxl_ring_set_dirty(qxl);
  586. break;
  587. default:
  588. /* nothing */
  589. break;
  590. }
  591. return wait;
  592. }
  593. /* called from spice server thread context only */
  594. static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
  595. {
  596. QXLReleaseRing *ring = &d->ram->release_ring;
  597. uint64_t *item;
  598. int notify;
  599. #define QXL_FREE_BUNCH_SIZE 32
  600. if (ring->prod - ring->cons + 1 == ring->num_items) {
  601. /* ring full -- can't push */
  602. return;
  603. }
  604. if (!flush && d->oom_running) {
  605. /* collect everything from oom handler before pushing */
  606. return;
  607. }
  608. if (!flush && d->num_free_res < QXL_FREE_BUNCH_SIZE) {
  609. /* collect a bit more before pushing */
  610. return;
  611. }
  612. SPICE_RING_PUSH(ring, notify);
  613. trace_qxl_ring_res_push(d->id, qxl_mode_to_string(d->mode),
  614. d->guest_surfaces.count, d->num_free_res,
  615. d->last_release, notify ? "yes" : "no");
  616. trace_qxl_ring_res_push_rest(d->id, ring->prod - ring->cons,
  617. ring->num_items, ring->prod, ring->cons);
  618. if (notify) {
  619. qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
  620. }
  621. SPICE_RING_PROD_ITEM(d, ring, item);
  622. if (!item) {
  623. return;
  624. }
  625. *item = 0;
  626. d->num_free_res = 0;
  627. d->last_release = NULL;
  628. qxl_ring_set_dirty(d);
  629. }
  630. /* called from spice server thread context only */
  631. static void interface_release_resource(QXLInstance *sin,
  632. struct QXLReleaseInfoExt ext)
  633. {
  634. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  635. QXLReleaseRing *ring;
  636. uint64_t *item, id;
  637. if (ext.group_id == MEMSLOT_GROUP_HOST) {
  638. /* host group -> vga mode update request */
  639. qemu_spice_destroy_update(&qxl->ssd, (void *)(intptr_t)ext.info->id);
  640. return;
  641. }
  642. /*
  643. * ext->info points into guest-visible memory
  644. * pci bar 0, $command.release_info
  645. */
  646. ring = &qxl->ram->release_ring;
  647. SPICE_RING_PROD_ITEM(qxl, ring, item);
  648. if (!item) {
  649. return;
  650. }
  651. if (*item == 0) {
  652. /* stick head into the ring */
  653. id = ext.info->id;
  654. ext.info->next = 0;
  655. qxl_ram_set_dirty(qxl, &ext.info->next);
  656. *item = id;
  657. qxl_ring_set_dirty(qxl);
  658. } else {
  659. /* append item to the list */
  660. qxl->last_release->next = ext.info->id;
  661. qxl_ram_set_dirty(qxl, &qxl->last_release->next);
  662. ext.info->next = 0;
  663. qxl_ram_set_dirty(qxl, &ext.info->next);
  664. }
  665. qxl->last_release = ext.info;
  666. qxl->num_free_res++;
  667. trace_qxl_ring_res_put(qxl->id, qxl->num_free_res);
  668. qxl_push_free_res(qxl, 0);
  669. }
  670. /* called from spice server thread context only */
  671. static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *ext)
  672. {
  673. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  674. QXLCursorRing *ring;
  675. QXLCommand *cmd;
  676. int notify;
  677. trace_qxl_ring_cursor_check(qxl->id, qxl_mode_to_string(qxl->mode));
  678. switch (qxl->mode) {
  679. case QXL_MODE_COMPAT:
  680. case QXL_MODE_NATIVE:
  681. case QXL_MODE_UNDEFINED:
  682. ring = &qxl->ram->cursor_ring;
  683. if (SPICE_RING_IS_EMPTY(ring)) {
  684. return false;
  685. }
  686. SPICE_RING_CONS_ITEM(qxl, ring, cmd);
  687. if (!cmd) {
  688. return false;
  689. }
  690. ext->cmd = *cmd;
  691. ext->group_id = MEMSLOT_GROUP_GUEST;
  692. ext->flags = qxl->cmdflags;
  693. SPICE_RING_POP(ring, notify);
  694. qxl_ring_set_dirty(qxl);
  695. if (notify) {
  696. qxl_send_events(qxl, QXL_INTERRUPT_CURSOR);
  697. }
  698. qxl->guest_primary.commands++;
  699. qxl_track_command(qxl, ext);
  700. qxl_log_command(qxl, "csr", ext);
  701. if (qxl->id == 0) {
  702. qxl_render_cursor(qxl, ext);
  703. }
  704. trace_qxl_ring_cursor_get(qxl->id, qxl_mode_to_string(qxl->mode));
  705. return true;
  706. default:
  707. return false;
  708. }
  709. }
  710. /* called from spice server thread context only */
  711. static int interface_req_cursor_notification(QXLInstance *sin)
  712. {
  713. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  714. int wait = 1;
  715. trace_qxl_ring_cursor_req_notification(qxl->id);
  716. switch (qxl->mode) {
  717. case QXL_MODE_COMPAT:
  718. case QXL_MODE_NATIVE:
  719. case QXL_MODE_UNDEFINED:
  720. SPICE_RING_CONS_WAIT(&qxl->ram->cursor_ring, wait);
  721. qxl_ring_set_dirty(qxl);
  722. break;
  723. default:
  724. /* nothing */
  725. break;
  726. }
  727. return wait;
  728. }
  729. /* called from spice server thread context */
  730. static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
  731. {
  732. /*
  733. * Called by spice-server as a result of a QXL_CMD_UPDATE which is not in
  734. * use by xf86-video-qxl and is defined out in the qxl windows driver.
  735. * Probably was at some earlier version that is prior to git start (2009),
  736. * and is still guest trigerrable.
  737. */
  738. fprintf(stderr, "%s: deprecated\n", __func__);
  739. }
  740. /* called from spice server thread context only */
  741. static int interface_flush_resources(QXLInstance *sin)
  742. {
  743. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  744. int ret;
  745. ret = qxl->num_free_res;
  746. if (ret) {
  747. qxl_push_free_res(qxl, 1);
  748. }
  749. return ret;
  750. }
  751. static void qxl_create_guest_primary_complete(PCIQXLDevice *d);
  752. /* called from spice server thread context only */
  753. static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
  754. {
  755. uint32_t current_async;
  756. qemu_mutex_lock(&qxl->async_lock);
  757. current_async = qxl->current_async;
  758. qxl->current_async = QXL_UNDEFINED_IO;
  759. qemu_mutex_unlock(&qxl->async_lock);
  760. trace_qxl_interface_async_complete_io(qxl->id, current_async, cookie);
  761. if (!cookie) {
  762. fprintf(stderr, "qxl: %s: error, cookie is NULL\n", __func__);
  763. return;
  764. }
  765. if (cookie && current_async != cookie->io) {
  766. fprintf(stderr,
  767. "qxl: %s: error: current_async = %d != %"
  768. PRId64 " = cookie->io\n", __func__, current_async, cookie->io);
  769. }
  770. switch (current_async) {
  771. case QXL_IO_MEMSLOT_ADD_ASYNC:
  772. case QXL_IO_DESTROY_PRIMARY_ASYNC:
  773. case QXL_IO_UPDATE_AREA_ASYNC:
  774. case QXL_IO_FLUSH_SURFACES_ASYNC:
  775. case QXL_IO_MONITORS_CONFIG_ASYNC:
  776. break;
  777. case QXL_IO_CREATE_PRIMARY_ASYNC:
  778. qxl_create_guest_primary_complete(qxl);
  779. break;
  780. case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
  781. qxl_spice_destroy_surfaces_complete(qxl);
  782. break;
  783. case QXL_IO_DESTROY_SURFACE_ASYNC:
  784. qxl_spice_destroy_surface_wait_complete(qxl, cookie->u.surface_id);
  785. break;
  786. default:
  787. fprintf(stderr, "qxl: %s: unexpected current_async %d\n", __func__,
  788. current_async);
  789. }
  790. qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD);
  791. }
  792. /* called from spice server thread context only */
  793. static void interface_update_area_complete(QXLInstance *sin,
  794. uint32_t surface_id,
  795. QXLRect *dirty, uint32_t num_updated_rects)
  796. {
  797. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  798. int i;
  799. int qxl_i;
  800. qemu_mutex_lock(&qxl->ssd.lock);
  801. if (surface_id != 0 || !qxl->render_update_cookie_num) {
  802. qemu_mutex_unlock(&qxl->ssd.lock);
  803. return;
  804. }
  805. trace_qxl_interface_update_area_complete(qxl->id, surface_id, dirty->left,
  806. dirty->right, dirty->top, dirty->bottom);
  807. trace_qxl_interface_update_area_complete_rest(qxl->id, num_updated_rects);
  808. if (qxl->num_dirty_rects + num_updated_rects > QXL_NUM_DIRTY_RECTS) {
  809. /*
  810. * overflow - treat this as a full update. Not expected to be common.
  811. */
  812. trace_qxl_interface_update_area_complete_overflow(qxl->id,
  813. QXL_NUM_DIRTY_RECTS);
  814. qxl->guest_primary.resized = 1;
  815. }
  816. if (qxl->guest_primary.resized) {
  817. /*
  818. * Don't bother copying or scheduling the bh since we will flip
  819. * the whole area anyway on completion of the update_area async call
  820. */
  821. qemu_mutex_unlock(&qxl->ssd.lock);
  822. return;
  823. }
  824. qxl_i = qxl->num_dirty_rects;
  825. for (i = 0; i < num_updated_rects; i++) {
  826. qxl->dirty[qxl_i++] = dirty[i];
  827. }
  828. qxl->num_dirty_rects += num_updated_rects;
  829. trace_qxl_interface_update_area_complete_schedule_bh(qxl->id,
  830. qxl->num_dirty_rects);
  831. qemu_bh_schedule(qxl->update_area_bh);
  832. qemu_mutex_unlock(&qxl->ssd.lock);
  833. }
  834. /* called from spice server thread context only */
  835. static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
  836. {
  837. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  838. QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
  839. switch (cookie->type) {
  840. case QXL_COOKIE_TYPE_IO:
  841. interface_async_complete_io(qxl, cookie);
  842. g_free(cookie);
  843. break;
  844. case QXL_COOKIE_TYPE_RENDER_UPDATE_AREA:
  845. qxl_render_update_area_done(qxl, cookie);
  846. break;
  847. case QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG:
  848. break;
  849. default:
  850. fprintf(stderr, "qxl: %s: unexpected cookie type %d\n",
  851. __func__, cookie->type);
  852. g_free(cookie);
  853. }
  854. }
  855. /* called from spice server thread context only */
  856. static void interface_set_client_capabilities(QXLInstance *sin,
  857. uint8_t client_present,
  858. uint8_t caps[58])
  859. {
  860. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  861. if (qxl->revision < 4) {
  862. trace_qxl_set_client_capabilities_unsupported_by_revision(qxl->id,
  863. qxl->revision);
  864. return;
  865. }
  866. if (runstate_check(RUN_STATE_INMIGRATE) ||
  867. runstate_check(RUN_STATE_POSTMIGRATE)) {
  868. return;
  869. }
  870. qxl->shadow_rom.client_present = client_present;
  871. memcpy(qxl->shadow_rom.client_capabilities, caps,
  872. sizeof(qxl->shadow_rom.client_capabilities));
  873. qxl->rom->client_present = client_present;
  874. memcpy(qxl->rom->client_capabilities, caps,
  875. sizeof(qxl->rom->client_capabilities));
  876. qxl_rom_set_dirty(qxl);
  877. qxl_send_events(qxl, QXL_INTERRUPT_CLIENT);
  878. }
  879. static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
  880. {
  881. /*
  882. * zlib xors the seed with 0xffffffff, and xors the result
  883. * again with 0xffffffff; Both are not done with linux's crc32,
  884. * which we want to be compatible with, so undo that.
  885. */
  886. return crc32(0xffffffff, p, len) ^ 0xffffffff;
  887. }
  888. /* called from main context only */
  889. static int interface_client_monitors_config(QXLInstance *sin,
  890. VDAgentMonitorsConfig *monitors_config)
  891. {
  892. PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  893. QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
  894. int i;
  895. if (qxl->revision < 4) {
  896. trace_qxl_client_monitors_config_unsupported_by_device(qxl->id,
  897. qxl->revision);
  898. return 0;
  899. }
  900. /*
  901. * Older windows drivers set int_mask to 0 when their ISR is called,
  902. * then later set it to ~0. So it doesn't relate to the actual interrupts
  903. * handled. However, they are old, so clearly they don't support this
  904. * interrupt
  905. */
  906. if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 ||
  907. !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) {
  908. trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id,
  909. qxl->ram->int_mask,
  910. monitors_config);
  911. return 0;
  912. }
  913. if (!monitors_config) {
  914. return 1;
  915. }
  916. memset(&rom->client_monitors_config, 0,
  917. sizeof(rom->client_monitors_config));
  918. rom->client_monitors_config.count = monitors_config->num_of_monitors;
  919. /* monitors_config->flags ignored */
  920. if (rom->client_monitors_config.count >=
  921. ARRAY_SIZE(rom->client_monitors_config.heads)) {
  922. trace_qxl_client_monitors_config_capped(qxl->id,
  923. monitors_config->num_of_monitors,
  924. ARRAY_SIZE(rom->client_monitors_config.heads));
  925. rom->client_monitors_config.count =
  926. ARRAY_SIZE(rom->client_monitors_config.heads);
  927. }
  928. for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
  929. VDAgentMonConfig *monitor = &monitors_config->monitors[i];
  930. QXLURect *rect = &rom->client_monitors_config.heads[i];
  931. /* monitor->depth ignored */
  932. rect->left = monitor->x;
  933. rect->top = monitor->y;
  934. rect->right = monitor->x + monitor->width;
  935. rect->bottom = monitor->y + monitor->height;
  936. }
  937. rom->client_monitors_config_crc = qxl_crc32(
  938. (const uint8_t *)&rom->client_monitors_config,
  939. sizeof(rom->client_monitors_config));
  940. trace_qxl_client_monitors_config_crc(qxl->id,
  941. sizeof(rom->client_monitors_config),
  942. rom->client_monitors_config_crc);
  943. trace_qxl_interrupt_client_monitors_config(qxl->id,
  944. rom->client_monitors_config.count,
  945. rom->client_monitors_config.heads);
  946. qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
  947. return 1;
  948. }
  949. static const QXLInterface qxl_interface = {
  950. .base.type = SPICE_INTERFACE_QXL,
  951. .base.description = "qxl gpu",
  952. .base.major_version = SPICE_INTERFACE_QXL_MAJOR,
  953. .base.minor_version = SPICE_INTERFACE_QXL_MINOR,
  954. .attache_worker = interface_attach_worker,
  955. .set_compression_level = interface_set_compression_level,
  956. .set_mm_time = interface_set_mm_time,
  957. .get_init_info = interface_get_init_info,
  958. /* the callbacks below are called from spice server thread context */
  959. .get_command = interface_get_command,
  960. .req_cmd_notification = interface_req_cmd_notification,
  961. .release_resource = interface_release_resource,
  962. .get_cursor_command = interface_get_cursor_command,
  963. .req_cursor_notification = interface_req_cursor_notification,
  964. .notify_update = interface_notify_update,
  965. .flush_resources = interface_flush_resources,
  966. .async_complete = interface_async_complete,
  967. .update_area_complete = interface_update_area_complete,
  968. .set_client_capabilities = interface_set_client_capabilities,
  969. .client_monitors_config = interface_client_monitors_config,
  970. };
  971. static void qxl_enter_vga_mode(PCIQXLDevice *d)
  972. {
  973. if (d->mode == QXL_MODE_VGA) {
  974. return;
  975. }
  976. trace_qxl_enter_vga_mode(d->id);
  977. #if SPICE_SERVER_VERSION >= 0x000c03 /* release 0.12.3 */
  978. spice_qxl_driver_unload(&d->ssd.qxl);
  979. #endif
  980. qemu_spice_create_host_primary(&d->ssd);
  981. d->mode = QXL_MODE_VGA;
  982. vga_dirty_log_start(&d->vga);
  983. graphic_hw_update(d->vga.con);
  984. }
  985. static void qxl_exit_vga_mode(PCIQXLDevice *d)
  986. {
  987. if (d->mode != QXL_MODE_VGA) {
  988. return;
  989. }
  990. trace_qxl_exit_vga_mode(d->id);
  991. vga_dirty_log_stop(&d->vga);
  992. qxl_destroy_primary(d, QXL_SYNC);
  993. }
  994. static void qxl_update_irq(PCIQXLDevice *d)
  995. {
  996. uint32_t pending = le32_to_cpu(d->ram->int_pending);
  997. uint32_t mask = le32_to_cpu(d->ram->int_mask);
  998. int level = !!(pending & mask);
  999. pci_set_irq(&d->pci, level);
  1000. qxl_ring_set_dirty(d);
  1001. }
  1002. static void qxl_check_state(PCIQXLDevice *d)
  1003. {
  1004. QXLRam *ram = d->ram;
  1005. int spice_display_running = qemu_spice_display_is_running(&d->ssd);
  1006. assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
  1007. assert(!spice_display_running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
  1008. }
  1009. static void qxl_reset_state(PCIQXLDevice *d)
  1010. {
  1011. QXLRom *rom = d->rom;
  1012. qxl_check_state(d);
  1013. d->shadow_rom.update_id = cpu_to_le32(0);
  1014. *rom = d->shadow_rom;
  1015. qxl_rom_set_dirty(d);
  1016. init_qxl_ram(d);
  1017. d->num_free_res = 0;
  1018. d->last_release = NULL;
  1019. memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));
  1020. qxl_update_irq(d);
  1021. }
  1022. static void qxl_soft_reset(PCIQXLDevice *d)
  1023. {
  1024. trace_qxl_soft_reset(d->id);
  1025. qxl_check_state(d);
  1026. qxl_clear_guest_bug(d);
  1027. d->current_async = QXL_UNDEFINED_IO;
  1028. if (d->id == 0) {
  1029. qxl_enter_vga_mode(d);
  1030. } else {
  1031. d->mode = QXL_MODE_UNDEFINED;
  1032. }
  1033. }
  1034. static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
  1035. {
  1036. bool startstop = qemu_spice_display_is_running(&d->ssd);
  1037. trace_qxl_hard_reset(d->id, loadvm);
  1038. if (startstop) {
  1039. qemu_spice_display_stop();
  1040. }
  1041. qxl_spice_reset_cursor(d);
  1042. qxl_spice_reset_image_cache(d);
  1043. qxl_reset_surfaces(d);
  1044. qxl_reset_memslots(d);
  1045. /* pre loadvm reset must not touch QXLRam. This lives in
  1046. * device memory, is migrated together with RAM and thus
  1047. * already loaded at this point */
  1048. if (!loadvm) {
  1049. qxl_reset_state(d);
  1050. }
  1051. qemu_spice_create_host_memslot(&d->ssd);
  1052. qxl_soft_reset(d);
  1053. if (startstop) {
  1054. qemu_spice_display_start();
  1055. }
  1056. }
  1057. static void qxl_reset_handler(DeviceState *dev)
  1058. {
  1059. PCIQXLDevice *d = DO_UPCAST(PCIQXLDevice, pci.qdev, dev);
  1060. qxl_hard_reset(d, 0);
  1061. }
  1062. static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
  1063. {
  1064. VGACommonState *vga = opaque;
  1065. PCIQXLDevice *qxl = container_of(vga, PCIQXLDevice, vga);
  1066. trace_qxl_io_write_vga(qxl->id, qxl_mode_to_string(qxl->mode), addr, val);
  1067. if (qxl->mode != QXL_MODE_VGA) {
  1068. qxl_destroy_primary(qxl, QXL_SYNC);
  1069. qxl_soft_reset(qxl);
  1070. }
  1071. vga_ioport_write(opaque, addr, val);
  1072. }
  1073. static const MemoryRegionPortio qxl_vga_portio_list[] = {
  1074. { 0x04, 2, 1, .read = vga_ioport_read,
  1075. .write = qxl_vga_ioport_write }, /* 3b4 */
  1076. { 0x0a, 1, 1, .read = vga_ioport_read,
  1077. .write = qxl_vga_ioport_write }, /* 3ba */
  1078. { 0x10, 16, 1, .read = vga_ioport_read,
  1079. .write = qxl_vga_ioport_write }, /* 3c0 */
  1080. { 0x24, 2, 1, .read = vga_ioport_read,
  1081. .write = qxl_vga_ioport_write }, /* 3d4 */
  1082. { 0x2a, 1, 1, .read = vga_ioport_read,
  1083. .write = qxl_vga_ioport_write }, /* 3da */
  1084. PORTIO_END_OF_LIST(),
  1085. };
  1086. static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
  1087. qxl_async_io async)
  1088. {
  1089. static const int regions[] = {
  1090. QXL_RAM_RANGE_INDEX,
  1091. QXL_VRAM_RANGE_INDEX,
  1092. QXL_VRAM64_RANGE_INDEX,
  1093. };
  1094. uint64_t guest_start;
  1095. uint64_t guest_end;
  1096. int pci_region;
  1097. pcibus_t pci_start;
  1098. pcibus_t pci_end;
  1099. intptr_t virt_start;
  1100. QXLDevMemSlot memslot;
  1101. int i;
  1102. guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);
  1103. guest_end = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);
  1104. trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
  1105. if (slot_id >= NUM_MEMSLOTS) {
  1106. qxl_set_guest_bug(d, "%s: slot_id >= NUM_MEMSLOTS %d >= %d", __func__,
  1107. slot_id, NUM_MEMSLOTS);
  1108. return 1;
  1109. }
  1110. if (guest_start > guest_end) {
  1111. qxl_set_guest_bug(d, "%s: guest_start > guest_end 0x%" PRIx64
  1112. " > 0x%" PRIx64, __func__, guest_start, guest_end);
  1113. return 1;
  1114. }
  1115. for (i = 0; i < ARRAY_SIZE(regions); i++) {
  1116. pci_region = regions[i];
  1117. pci_start = d->pci.io_regions[pci_region].addr;
  1118. pci_end = pci_start + d->pci.io_regions[pci_region].size;
  1119. /* mapped? */
  1120. if (pci_start == -1) {
  1121. continue;
  1122. }
  1123. /* start address in range ? */
  1124. if (guest_start < pci_start || guest_start > pci_end) {
  1125. continue;
  1126. }
  1127. /* end address in range ? */
  1128. if (guest_end > pci_end) {
  1129. continue;
  1130. }
  1131. /* passed */
  1132. break;
  1133. }
  1134. if (i == ARRAY_SIZE(regions)) {
  1135. qxl_set_guest_bug(d, "%s: finished loop without match", __func__);
  1136. return 1;
  1137. }
  1138. switch (pci_region) {
  1139. case QXL_RAM_RANGE_INDEX:
  1140. virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
  1141. break;
  1142. case QXL_VRAM_RANGE_INDEX:
  1143. case 4 /* vram 64bit */:
  1144. virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
  1145. break;
  1146. default:
  1147. /* should not happen */
  1148. qxl_set_guest_bug(d, "%s: pci_region = %d", __func__, pci_region);
  1149. return 1;
  1150. }
  1151. memslot.slot_id = slot_id;
  1152. memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */
  1153. memslot.virt_start = virt_start + (guest_start - pci_start);
  1154. memslot.virt_end = virt_start + (guest_end - pci_start);
  1155. memslot.addr_delta = memslot.virt_start - delta;
  1156. memslot.generation = d->rom->slot_generation = 0;
  1157. qxl_rom_set_dirty(d);
  1158. qemu_spice_add_memslot(&d->ssd, &memslot, async);
  1159. d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
  1160. d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
  1161. d->guest_slots[slot_id].delta = delta;
  1162. d->guest_slots[slot_id].active = 1;
  1163. return 0;
  1164. }
  1165. static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
  1166. {
  1167. qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
  1168. d->guest_slots[slot_id].active = 0;
  1169. }
  1170. static void qxl_reset_memslots(PCIQXLDevice *d)
  1171. {
  1172. qxl_spice_reset_memslots(d);
  1173. memset(&d->guest_slots, 0, sizeof(d->guest_slots));
  1174. }
  1175. static void qxl_reset_surfaces(PCIQXLDevice *d)
  1176. {
  1177. trace_qxl_reset_surfaces(d->id);
  1178. d->mode = QXL_MODE_UNDEFINED;
  1179. qxl_spice_destroy_surfaces(d, QXL_SYNC);
  1180. }
  1181. /* can be also called from spice server thread context */
  1182. void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
  1183. {
  1184. uint64_t phys = le64_to_cpu(pqxl);
  1185. uint32_t slot = (phys >> (64 - 8)) & 0xff;
  1186. uint64_t offset = phys & 0xffffffffffff;
  1187. switch (group_id) {
  1188. case MEMSLOT_GROUP_HOST:
  1189. return (void *)(intptr_t)offset;
  1190. case MEMSLOT_GROUP_GUEST:
  1191. if (slot >= NUM_MEMSLOTS) {
  1192. qxl_set_guest_bug(qxl, "slot too large %d >= %d", slot,
  1193. NUM_MEMSLOTS);
  1194. return NULL;
  1195. }
  1196. if (!qxl->guest_slots[slot].active) {
  1197. qxl_set_guest_bug(qxl, "inactive slot %d\n", slot);
  1198. return NULL;
  1199. }
  1200. if (offset < qxl->guest_slots[slot].delta) {
  1201. qxl_set_guest_bug(qxl,
  1202. "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
  1203. slot, offset, qxl->guest_slots[slot].delta);
  1204. return NULL;
  1205. }
  1206. offset -= qxl->guest_slots[slot].delta;
  1207. if (offset > qxl->guest_slots[slot].size) {
  1208. qxl_set_guest_bug(qxl,
  1209. "slot %d offset %"PRIu64" > size %"PRIu64"\n",
  1210. slot, offset, qxl->guest_slots[slot].size);
  1211. return NULL;
  1212. }
  1213. return qxl->guest_slots[slot].ptr + offset;
  1214. }
  1215. return NULL;
  1216. }
  1217. static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
  1218. {
  1219. /* for local rendering */
  1220. qxl_render_resize(qxl);
  1221. }
  1222. static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
  1223. qxl_async_io async)
  1224. {
  1225. QXLDevSurfaceCreate surface;
  1226. QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
  1227. uint32_t requested_height = le32_to_cpu(sc->height);
  1228. int requested_stride = le32_to_cpu(sc->stride);
  1229. if (requested_stride == INT32_MIN ||
  1230. abs(requested_stride) * (uint64_t)requested_height
  1231. > qxl->vgamem_size) {
  1232. qxl_set_guest_bug(qxl, "%s: requested primary larger than framebuffer"
  1233. " stride %d x height %" PRIu32 " > %" PRIu32,
  1234. __func__, requested_stride, requested_height,
  1235. qxl->vgamem_size);
  1236. return;
  1237. }
  1238. if (qxl->mode == QXL_MODE_NATIVE) {
  1239. qxl_set_guest_bug(qxl, "%s: nop since already in QXL_MODE_NATIVE",
  1240. __func__);
  1241. }
  1242. qxl_exit_vga_mode(qxl);
  1243. surface.format = le32_to_cpu(sc->format);
  1244. surface.height = le32_to_cpu(sc->height);
  1245. surface.mem = le64_to_cpu(sc->mem);
  1246. surface.position = le32_to_cpu(sc->position);
  1247. surface.stride = le32_to_cpu(sc->stride);
  1248. surface.width = le32_to_cpu(sc->width);
  1249. surface.type = le32_to_cpu(sc->type);
  1250. surface.flags = le32_to_cpu(sc->flags);
  1251. trace_qxl_create_guest_primary(qxl->id, sc->width, sc->height, sc->mem,
  1252. sc->format, sc->position);
  1253. trace_qxl_create_guest_primary_rest(qxl->id, sc->stride, sc->type,
  1254. sc->flags);
  1255. if ((surface.stride & 0x3) != 0) {
  1256. qxl_set_guest_bug(qxl, "primary surface stride = %d %% 4 != 0",
  1257. surface.stride);
  1258. return;
  1259. }
  1260. surface.mouse_mode = true;
  1261. surface.group_id = MEMSLOT_GROUP_GUEST;
  1262. if (loadvm) {
  1263. surface.flags |= QXL_SURF_FLAG_KEEP_DATA;
  1264. }
  1265. qxl->mode = QXL_MODE_NATIVE;
  1266. qxl->cmdflags = 0;
  1267. qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface, async);
  1268. if (async == QXL_SYNC) {
  1269. qxl_create_guest_primary_complete(qxl);
  1270. }
  1271. }
  1272. /* return 1 if surface destoy was initiated (in QXL_ASYNC case) or
  1273. * done (in QXL_SYNC case), 0 otherwise. */
  1274. static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
  1275. {
  1276. if (d->mode == QXL_MODE_UNDEFINED) {
  1277. return 0;
  1278. }
  1279. trace_qxl_destroy_primary(d->id);
  1280. d->mode = QXL_MODE_UNDEFINED;
  1281. qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
  1282. qxl_spice_reset_cursor(d);
  1283. return 1;
  1284. }
  1285. static void qxl_set_mode(PCIQXLDevice *d, unsigned int modenr, int loadvm)
  1286. {
  1287. pcibus_t start = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
  1288. pcibus_t end = d->pci.io_regions[QXL_RAM_RANGE_INDEX].size + start;
  1289. QXLMode *mode = d->modes->modes + modenr;
  1290. uint64_t devmem = d->pci.io_regions[QXL_RAM_RANGE_INDEX].addr;
  1291. QXLMemSlot slot = {
  1292. .mem_start = start,
  1293. .mem_end = end
  1294. };
  1295. if (modenr >= d->modes->n_modes) {
  1296. qxl_set_guest_bug(d, "mode number out of range");
  1297. return;
  1298. }
  1299. QXLSurfaceCreate surface = {
  1300. .width = mode->x_res,
  1301. .height = mode->y_res,
  1302. .stride = -mode->x_res * 4,
  1303. .format = SPICE_SURFACE_FMT_32_xRGB,
  1304. .flags = loadvm ? QXL_SURF_FLAG_KEEP_DATA : 0,
  1305. .mouse_mode = true,
  1306. .mem = devmem + d->shadow_rom.draw_area_offset,
  1307. };
  1308. trace_qxl_set_mode(d->id, modenr, mode->x_res, mode->y_res, mode->bits,
  1309. devmem);
  1310. if (!loadvm) {
  1311. qxl_hard_reset(d, 0);
  1312. }
  1313. d->guest_slots[0].slot = slot;
  1314. assert(qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0);
  1315. d->guest_primary.surface = surface;
  1316. qxl_create_guest_primary(d, 0, QXL_SYNC);
  1317. d->mode = QXL_MODE_COMPAT;
  1318. d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
  1319. if (mode->bits == 16) {
  1320. d->cmdflags |= QXL_COMMAND_FLAG_COMPAT_16BPP;
  1321. }
  1322. d->shadow_rom.mode = cpu_to_le32(modenr);
  1323. d->rom->mode = cpu_to_le32(modenr);
  1324. qxl_rom_set_dirty(d);
  1325. }
  1326. static void ioport_write(void *opaque, hwaddr addr,
  1327. uint64_t val, unsigned size)
  1328. {
  1329. PCIQXLDevice *d = opaque;
  1330. uint32_t io_port = addr;
  1331. qxl_async_io async = QXL_SYNC;
  1332. uint32_t orig_io_port = io_port;
  1333. if (d->guest_bug && io_port != QXL_IO_RESET) {
  1334. return;
  1335. }
  1336. if (d->revision <= QXL_REVISION_STABLE_V10 &&
  1337. io_port > QXL_IO_FLUSH_RELEASE) {
  1338. qxl_set_guest_bug(d, "unsupported io %d for revision %d\n",
  1339. io_port, d->revision);
  1340. return;
  1341. }
  1342. switch (io_port) {
  1343. case QXL_IO_RESET:
  1344. case QXL_IO_SET_MODE:
  1345. case QXL_IO_MEMSLOT_ADD:
  1346. case QXL_IO_MEMSLOT_DEL:
  1347. case QXL_IO_CREATE_PRIMARY:
  1348. case QXL_IO_UPDATE_IRQ:
  1349. case QXL_IO_LOG:
  1350. case QXL_IO_MEMSLOT_ADD_ASYNC:
  1351. case QXL_IO_CREATE_PRIMARY_ASYNC:
  1352. break;
  1353. default:
  1354. if (d->mode != QXL_MODE_VGA) {
  1355. break;
  1356. }
  1357. trace_qxl_io_unexpected_vga_mode(d->id,
  1358. addr, val, io_port_to_string(io_port));
  1359. /* be nice to buggy guest drivers */
  1360. if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
  1361. io_port < QXL_IO_RANGE_SIZE) {
  1362. qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
  1363. }
  1364. return;
  1365. }
  1366. /* we change the io_port to avoid ifdeffery in the main switch */
  1367. orig_io_port = io_port;
  1368. switch (io_port) {
  1369. case QXL_IO_UPDATE_AREA_ASYNC:
  1370. io_port = QXL_IO_UPDATE_AREA;
  1371. goto async_common;
  1372. case QXL_IO_MEMSLOT_ADD_ASYNC:
  1373. io_port = QXL_IO_MEMSLOT_ADD;
  1374. goto async_common;
  1375. case QXL_IO_CREATE_PRIMARY_ASYNC:
  1376. io_port = QXL_IO_CREATE_PRIMARY;
  1377. goto async_common;
  1378. case QXL_IO_DESTROY_PRIMARY_ASYNC:
  1379. io_port = QXL_IO_DESTROY_PRIMARY;
  1380. goto async_common;
  1381. case QXL_IO_DESTROY_SURFACE_ASYNC:
  1382. io_port = QXL_IO_DESTROY_SURFACE_WAIT;
  1383. goto async_common;
  1384. case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
  1385. io_port = QXL_IO_DESTROY_ALL_SURFACES;
  1386. goto async_common;
  1387. case QXL_IO_FLUSH_SURFACES_ASYNC:
  1388. case QXL_IO_MONITORS_CONFIG_ASYNC:
  1389. async_common:
  1390. async = QXL_ASYNC;
  1391. qemu_mutex_lock(&d->async_lock);
  1392. if (d->current_async != QXL_UNDEFINED_IO) {
  1393. qxl_set_guest_bug(d, "%d async started before last (%d) complete",
  1394. io_port, d->current_async);
  1395. qemu_mutex_unlock(&d->async_lock);
  1396. return;
  1397. }
  1398. d->current_async = orig_io_port;
  1399. qemu_mutex_unlock(&d->async_lock);
  1400. break;
  1401. default:
  1402. break;
  1403. }
  1404. trace_qxl_io_write(d->id, qxl_mode_to_string(d->mode),
  1405. addr, io_port_to_string(addr),
  1406. val, size, async);
  1407. switch (io_port) {
  1408. case QXL_IO_UPDATE_AREA:
  1409. {
  1410. QXLCookie *cookie = NULL;
  1411. QXLRect update = d->ram->update_area;
  1412. if (d->ram->update_surface > d->ssd.num_surfaces) {
  1413. qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
  1414. d->ram->update_surface);
  1415. break;
  1416. }
  1417. if (update.left >= update.right || update.top >= update.bottom ||
  1418. update.left < 0 || update.top < 0) {
  1419. qxl_set_guest_bug(d,
  1420. "QXL_IO_UPDATE_AREA: invalid area (%ux%u)x(%ux%u)\n",
  1421. update.left, update.top, update.right, update.bottom);
  1422. break;
  1423. }
  1424. if (async == QXL_ASYNC) {
  1425. cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
  1426. QXL_IO_UPDATE_AREA_ASYNC);
  1427. cookie->u.area = update;
  1428. }
  1429. qxl_spice_update_area(d, d->ram->update_surface,
  1430. cookie ? &cookie->u.area : &update,
  1431. NULL, 0, 0, async, cookie);
  1432. break;
  1433. }
  1434. case QXL_IO_NOTIFY_CMD:
  1435. qemu_spice_wakeup(&d->ssd);
  1436. break;
  1437. case QXL_IO_NOTIFY_CURSOR:
  1438. qemu_spice_wakeup(&d->ssd);
  1439. break;
  1440. case QXL_IO_UPDATE_IRQ:
  1441. qxl_update_irq(d);
  1442. break;
  1443. case QXL_IO_NOTIFY_OOM:
  1444. if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
  1445. break;
  1446. }
  1447. d->oom_running = 1;
  1448. qxl_spice_oom(d);
  1449. d->oom_running = 0;
  1450. break;
  1451. case QXL_IO_SET_MODE:
  1452. qxl_set_mode(d, val, 0);
  1453. break;
  1454. case QXL_IO_LOG:
  1455. trace_qxl_io_log(d->id, d->ram->log_buf);
  1456. if (d->guestdebug) {
  1457. fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,
  1458. qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), d->ram->log_buf);
  1459. }
  1460. break;
  1461. case QXL_IO_RESET:
  1462. qxl_hard_reset(d, 0);
  1463. break;
  1464. case QXL_IO_MEMSLOT_ADD:
  1465. if (val >= NUM_MEMSLOTS) {
  1466. qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
  1467. break;
  1468. }
  1469. if (d->guest_slots[val].active) {
  1470. qxl_set_guest_bug(d,
  1471. "QXL_IO_MEMSLOT_ADD: memory slot already active");
  1472. break;
  1473. }
  1474. d->guest_slots[val].slot = d->ram->mem_slot;
  1475. qxl_add_memslot(d, val, 0, async);
  1476. break;
  1477. case QXL_IO_MEMSLOT_DEL:
  1478. if (val >= NUM_MEMSLOTS) {
  1479. qxl_set_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
  1480. break;
  1481. }
  1482. qxl_del_memslot(d, val);
  1483. break;
  1484. case QXL_IO_CREATE_PRIMARY:
  1485. if (val != 0) {
  1486. qxl_set_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0",
  1487. async);
  1488. goto cancel_async;
  1489. }
  1490. d->guest_primary.surface = d->ram->create_surface;
  1491. qxl_create_guest_primary(d, 0, async);
  1492. break;
  1493. case QXL_IO_DESTROY_PRIMARY:
  1494. if (val != 0) {
  1495. qxl_set_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
  1496. async);
  1497. goto cancel_async;
  1498. }
  1499. if (!qxl_destroy_primary(d, async)) {
  1500. trace_qxl_io_destroy_primary_ignored(d->id,
  1501. qxl_mode_to_string(d->mode));
  1502. goto cancel_async;
  1503. }
  1504. break;
  1505. case QXL_IO_DESTROY_SURFACE_WAIT:
  1506. if (val >= d->ssd.num_surfaces) {
  1507. qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"
  1508. "%" PRIu64 " >= NUM_SURFACES", async, val);
  1509. goto cancel_async;
  1510. }
  1511. qxl_spice_destroy_surface_wait(d, val, async);
  1512. break;
  1513. case QXL_IO_FLUSH_RELEASE: {
  1514. QXLReleaseRing *ring = &d->ram->release_ring;
  1515. if (ring->prod - ring->cons + 1 == ring->num_items) {
  1516. fprintf(stderr,
  1517. "ERROR: no flush, full release ring [p%d,%dc]\n",
  1518. ring->prod, ring->cons);
  1519. }
  1520. qxl_push_free_res(d, 1 /* flush */);
  1521. break;
  1522. }
  1523. case QXL_IO_FLUSH_SURFACES_ASYNC:
  1524. qxl_spice_flush_surfaces_async(d);
  1525. break;
  1526. case QXL_IO_DESTROY_ALL_SURFACES:
  1527. d->mode = QXL_MODE_UNDEFINED;
  1528. qxl_spice_destroy_surfaces(d, async);
  1529. break;
  1530. case QXL_IO_MONITORS_CONFIG_ASYNC:
  1531. qxl_spice_monitors_config_async(d, 0);
  1532. break;
  1533. default:
  1534. qxl_set_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port);
  1535. }
  1536. return;
  1537. cancel_async:
  1538. if (async) {
  1539. qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
  1540. qemu_mutex_lock(&d->async_lock);
  1541. d->current_async = QXL_UNDEFINED_IO;
  1542. qemu_mutex_unlock(&d->async_lock);
  1543. }
  1544. }
  1545. static uint64_t ioport_read(void *opaque, hwaddr addr,
  1546. unsigned size)
  1547. {
  1548. PCIQXLDevice *qxl = opaque;
  1549. trace_qxl_io_read_unexpected(qxl->id);
  1550. return 0xff;
  1551. }
  1552. static const MemoryRegionOps qxl_io_ops = {
  1553. .read = ioport_read,
  1554. .write = ioport_write,
  1555. .valid = {
  1556. .min_access_size = 1,
  1557. .max_access_size = 1,
  1558. },
  1559. };
  1560. static void qxl_update_irq_bh(void *opaque)
  1561. {
  1562. PCIQXLDevice *d = opaque;
  1563. qxl_update_irq(d);
  1564. }
  1565. static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
  1566. {
  1567. uint32_t old_pending;
  1568. uint32_t le_events = cpu_to_le32(events);
  1569. trace_qxl_send_events(d->id, events);
  1570. if (!qemu_spice_display_is_running(&d->ssd)) {
  1571. /* spice-server tracks guest running state and should not do this */
  1572. fprintf(stderr, "%s: spice-server bug: guest stopped, ignoring\n",
  1573. __func__);
  1574. trace_qxl_send_events_vm_stopped(d->id, events);
  1575. return;
  1576. }
  1577. old_pending = atomic_fetch_or(&d->ram->int_pending, le_events);
  1578. if ((old_pending & le_events) == le_events) {
  1579. return;
  1580. }
  1581. qemu_bh_schedule(d->update_irq);
  1582. }
  1583. /* graphics console */
  1584. static void qxl_hw_update(void *opaque)
  1585. {
  1586. PCIQXLDevice *qxl = opaque;
  1587. VGACommonState *vga = &qxl->vga;
  1588. switch (qxl->mode) {
  1589. case QXL_MODE_VGA:
  1590. vga->hw_ops->gfx_update(vga);
  1591. break;
  1592. case QXL_MODE_COMPAT:
  1593. case QXL_MODE_NATIVE:
  1594. qxl_render_update(qxl);
  1595. break;
  1596. default:
  1597. break;
  1598. }
  1599. }
  1600. static void qxl_hw_invalidate(void *opaque)
  1601. {
  1602. PCIQXLDevice *qxl = opaque;
  1603. VGACommonState *vga = &qxl->vga;
  1604. if (qxl->mode == QXL_MODE_VGA) {
  1605. vga->hw_ops->invalidate(vga);
  1606. return;
  1607. }
  1608. }
  1609. static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
  1610. {
  1611. PCIQXLDevice *qxl = opaque;
  1612. VGACommonState *vga = &qxl->vga;
  1613. if (qxl->mode == QXL_MODE_VGA) {
  1614. vga->hw_ops->text_update(vga, chardata);
  1615. return;
  1616. }
  1617. }
  1618. static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
  1619. {
  1620. uintptr_t vram_start;
  1621. int i;
  1622. if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
  1623. return;
  1624. }
  1625. /* dirty the primary surface */
  1626. qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
  1627. qxl->shadow_rom.surface0_area_size);
  1628. vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
  1629. /* dirty the off-screen surfaces */
  1630. for (i = 0; i < qxl->ssd.num_surfaces; i++) {
  1631. QXLSurfaceCmd *cmd;
  1632. intptr_t surface_offset;
  1633. int surface_size;
  1634. if (qxl->guest_surfaces.cmds[i] == 0) {
  1635. continue;
  1636. }
  1637. cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
  1638. MEMSLOT_GROUP_GUEST);
  1639. assert(cmd);
  1640. assert(cmd->type == QXL_SURFACE_CMD_CREATE);
  1641. surface_offset = (intptr_t)qxl_phys2virt(qxl,
  1642. cmd->u.surface_create.data,
  1643. MEMSLOT_GROUP_GUEST);
  1644. assert(surface_offset);
  1645. surface_offset -= vram_start;
  1646. surface_size = cmd->u.surface_create.height *
  1647. abs(cmd->u.surface_create.stride);
  1648. trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);
  1649. qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
  1650. }
  1651. }
  1652. static void qxl_vm_change_state_handler(void *opaque, int running,
  1653. RunState state)
  1654. {
  1655. PCIQXLDevice *qxl = opaque;
  1656. if (running) {
  1657. /*
  1658. * if qxl_send_events was called from spice server context before
  1659. * migration ended, qxl_update_irq for these events might not have been
  1660. * called
  1661. */
  1662. qxl_update_irq(qxl);
  1663. } else {
  1664. /* make sure surfaces are saved before migration */
  1665. qxl_dirty_surfaces(qxl);
  1666. }
  1667. }
  1668. /* display change listener */
  1669. static void display_update(DisplayChangeListener *dcl,
  1670. int x, int y, int w, int h)
  1671. {
  1672. PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
  1673. if (qxl->mode == QXL_MODE_VGA) {
  1674. qemu_spice_display_update(&qxl->ssd, x, y, w, h);
  1675. }
  1676. }
  1677. static void display_switch(DisplayChangeListener *dcl,
  1678. struct DisplaySurface *surface)
  1679. {
  1680. PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
  1681. qxl->ssd.ds = surface;
  1682. if (qxl->mode == QXL_MODE_VGA) {
  1683. qemu_spice_display_switch(&qxl->ssd, surface);
  1684. }
  1685. }
  1686. static void display_refresh(DisplayChangeListener *dcl)
  1687. {
  1688. PCIQXLDevice *qxl = container_of(dcl, PCIQXLDevice, ssd.dcl);
  1689. if (qxl->mode == QXL_MODE_VGA) {
  1690. qemu_spice_display_refresh(&qxl->ssd);
  1691. } else {
  1692. qemu_mutex_lock(&qxl->ssd.lock);
  1693. qemu_spice_cursor_refresh_unlocked(&qxl->ssd);
  1694. qemu_mutex_unlock(&qxl->ssd.lock);
  1695. }
  1696. }
  1697. static DisplayChangeListenerOps display_listener_ops = {
  1698. .dpy_name = "spice/qxl",
  1699. .dpy_gfx_update = display_update,
  1700. .dpy_gfx_switch = display_switch,
  1701. .dpy_refresh = display_refresh,
  1702. };
  1703. static void qxl_init_ramsize(PCIQXLDevice *qxl)
  1704. {
  1705. /* vga mode framebuffer / primary surface (bar 0, first part) */
  1706. if (qxl->vgamem_size_mb < 8) {
  1707. qxl->vgamem_size_mb = 8;
  1708. }
  1709. qxl->vgamem_size = qxl->vgamem_size_mb * 1024 * 1024;
  1710. /* vga ram (bar 0, total) */
  1711. if (qxl->ram_size_mb != -1) {
  1712. qxl->vga.vram_size = qxl->ram_size_mb * 1024 * 1024;
  1713. }
  1714. if (qxl->vga.vram_size < qxl->vgamem_size * 2) {
  1715. qxl->vga.vram_size = qxl->vgamem_size * 2;
  1716. }
  1717. /* vram32 (surfaces, 32bit, bar 1) */
  1718. if (qxl->vram32_size_mb != -1) {
  1719. qxl->vram32_size = qxl->vram32_size_mb * 1024 * 1024;
  1720. }
  1721. if (qxl->vram32_size < 4096) {
  1722. qxl->vram32_size = 4096;
  1723. }
  1724. /* vram (surfaces, 64bit, bar 4+5) */
  1725. if (qxl->vram_size_mb != -1) {
  1726. qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
  1727. }
  1728. if (qxl->vram_size < qxl->vram32_size) {
  1729. qxl->vram_size = qxl->vram32_size;
  1730. }
  1731. if (qxl->revision == 1) {
  1732. qxl->vram32_size = 4096;
  1733. qxl->vram_size = 4096;
  1734. }
  1735. qxl->vgamem_size = msb_mask(qxl->vgamem_size * 2 - 1);
  1736. qxl->vga.vram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
  1737. qxl->vram32_size = msb_mask(qxl->vram32_size * 2 - 1);
  1738. qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
  1739. }
  1740. static int qxl_init_common(PCIQXLDevice *qxl)
  1741. {
  1742. uint8_t* config = qxl->pci.config;
  1743. uint32_t pci_device_rev;
  1744. uint32_t io_size;
  1745. qxl->mode = QXL_MODE_UNDEFINED;
  1746. qxl->generation = 1;
  1747. qxl->num_memslots = NUM_MEMSLOTS;
  1748. qemu_mutex_init(&qxl->track_lock);
  1749. qemu_mutex_init(&qxl->async_lock);
  1750. qxl->current_async = QXL_UNDEFINED_IO;
  1751. qxl->guest_bug = 0;
  1752. switch (qxl->revision) {
  1753. case 1: /* spice 0.4 -- qxl-1 */
  1754. pci_device_rev = QXL_REVISION_STABLE_V04;
  1755. io_size = 8;
  1756. break;
  1757. case 2: /* spice 0.6 -- qxl-2 */
  1758. pci_device_rev = QXL_REVISION_STABLE_V06;
  1759. io_size = 16;
  1760. break;
  1761. case 3: /* qxl-3 */
  1762. pci_device_rev = QXL_REVISION_STABLE_V10;
  1763. io_size = 32; /* PCI region size must be pow2 */
  1764. break;
  1765. case 4: /* qxl-4 */
  1766. pci_device_rev = QXL_REVISION_STABLE_V12;
  1767. io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
  1768. break;
  1769. default:
  1770. error_report("Invalid revision %d for qxl device (max %d)",
  1771. qxl->revision, QXL_DEFAULT_REVISION);
  1772. return -1;
  1773. }
  1774. pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
  1775. pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
  1776. qxl->rom_size = qxl_rom_size();
  1777. memory_region_init_ram(&qxl->rom_bar, OBJECT(qxl), "qxl.vrom",
  1778. qxl->rom_size);
  1779. vmstate_register_ram(&qxl->rom_bar, &qxl->pci.qdev);
  1780. init_qxl_rom(qxl);
  1781. init_qxl_ram(qxl);
  1782. qxl->guest_surfaces.cmds = g_new0(QXLPHYSICAL, qxl->ssd.num_surfaces);
  1783. memory_region_init_ram(&qxl->vram_bar, OBJECT(qxl), "qxl.vram",
  1784. qxl->vram_size);
  1785. vmstate_register_ram(&qxl->vram_bar, &qxl->pci.qdev);
  1786. memory_region_init_alias(&qxl->vram32_bar, OBJECT(qxl), "qxl.vram32",
  1787. &qxl->vram_bar, 0, qxl->vram32_size);
  1788. memory_region_init_io(&qxl->io_bar, OBJECT(qxl), &qxl_io_ops, qxl,
  1789. "qxl-ioports", io_size);
  1790. if (qxl->id == 0) {
  1791. vga_dirty_log_start(&qxl->vga);
  1792. }
  1793. memory_region_set_flush_coalesced(&qxl->io_bar);
  1794. pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
  1795. PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
  1796. pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
  1797. PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
  1798. pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
  1799. PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
  1800. pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
  1801. PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram32_bar);
  1802. if (qxl->vram32_size < qxl->vram_size) {
  1803. /*
  1804. * Make the 64bit vram bar show up only in case it is
  1805. * configured to be larger than the 32bit vram bar.
  1806. */
  1807. pci_register_bar(&qxl->pci, QXL_VRAM64_RANGE_INDEX,
  1808. PCI_BASE_ADDRESS_SPACE_MEMORY |
  1809. PCI_BASE_ADDRESS_MEM_TYPE_64 |
  1810. PCI_BASE_ADDRESS_MEM_PREFETCH,
  1811. &qxl->vram_bar);
  1812. }
  1813. /* print pci bar details */
  1814. dprint(qxl, 1, "ram/%s: %d MB [region 0]\n",
  1815. qxl->id == 0 ? "pri" : "sec",
  1816. qxl->vga.vram_size / (1024*1024));
  1817. dprint(qxl, 1, "vram/32: %d MB [region 1]\n",
  1818. qxl->vram32_size / (1024*1024));
  1819. dprint(qxl, 1, "vram/64: %d MB %s\n",
  1820. qxl->vram_size / (1024*1024),
  1821. qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
  1822. qxl->ssd.qxl.base.sif = &qxl_interface.base;
  1823. if (qemu_spice_add_display_interface(&qxl->ssd.qxl, qxl->vga.con) != 0) {
  1824. error_report("qxl interface %d.%d not supported by spice-server",
  1825. SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
  1826. return -1;
  1827. }
  1828. qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
  1829. qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
  1830. qxl_reset_state(qxl);
  1831. qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
  1832. return 0;
  1833. }
  1834. static const GraphicHwOps qxl_ops = {
  1835. .invalidate = qxl_hw_invalidate,
  1836. .gfx_update = qxl_hw_update,
  1837. .text_update = qxl_hw_text_update,
  1838. };
  1839. static int qxl_init_primary(PCIDevice *dev)
  1840. {
  1841. PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
  1842. VGACommonState *vga = &qxl->vga;
  1843. PortioList *qxl_vga_port_list = g_new(PortioList, 1);
  1844. int rc;
  1845. qxl->id = 0;
  1846. qxl_init_ramsize(qxl);
  1847. vga->vram_size_mb = qxl->vga.vram_size >> 20;
  1848. vga_common_init(vga, OBJECT(dev));
  1849. vga_init(vga, OBJECT(dev),
  1850. pci_address_space(dev), pci_address_space_io(dev), false);
  1851. portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list,
  1852. vga, "vga");
  1853. portio_list_set_flush_coalesced(qxl_vga_port_list);
  1854. portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
  1855. vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
  1856. qemu_spice_display_init_common(&qxl->ssd);
  1857. rc = qxl_init_common(qxl);
  1858. if (rc != 0) {
  1859. return rc;
  1860. }
  1861. qxl->ssd.dcl.ops = &display_listener_ops;
  1862. qxl->ssd.dcl.con = vga->con;
  1863. register_displaychangelistener(&qxl->ssd.dcl);
  1864. return rc;
  1865. }
  1866. static int qxl_init_secondary(PCIDevice *dev)
  1867. {
  1868. static int device_id = 1;
  1869. PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
  1870. qxl->id = device_id++;
  1871. qxl_init_ramsize(qxl);
  1872. memory_region_init_ram(&qxl->vga.vram, OBJECT(dev), "qxl.vgavram",
  1873. qxl->vga.vram_size);
  1874. vmstate_register_ram(&qxl->vga.vram, &qxl->pci.qdev);
  1875. qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
  1876. qxl->vga.con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
  1877. return qxl_init_common(qxl);
  1878. }
  1879. static void qxl_pre_save(void *opaque)
  1880. {
  1881. PCIQXLDevice* d = opaque;
  1882. uint8_t *ram_start = d->vga.vram_ptr;
  1883. trace_qxl_pre_save(d->id);
  1884. if (d->last_release == NULL) {
  1885. d->last_release_offset = 0;
  1886. } else {
  1887. d->last_release_offset = (uint8_t *)d->last_release - ram_start;
  1888. }
  1889. assert(d->last_release_offset < d->vga.vram_size);
  1890. }
  1891. static int qxl_pre_load(void *opaque)
  1892. {
  1893. PCIQXLDevice* d = opaque;
  1894. trace_qxl_pre_load(d->id);
  1895. qxl_hard_reset(d, 1);
  1896. qxl_exit_vga_mode(d);
  1897. return 0;
  1898. }
  1899. static void qxl_create_memslots(PCIQXLDevice *d)
  1900. {
  1901. int i;
  1902. for (i = 0; i < NUM_MEMSLOTS; i++) {
  1903. if (!d->guest_slots[i].active) {
  1904. continue;
  1905. }
  1906. qxl_add_memslot(d, i, 0, QXL_SYNC);
  1907. }
  1908. }
  1909. static int qxl_post_load(void *opaque, int version)
  1910. {
  1911. PCIQXLDevice* d = opaque;
  1912. uint8_t *ram_start = d->vga.vram_ptr;
  1913. QXLCommandExt *cmds;
  1914. int in, out, newmode;
  1915. assert(d->last_release_offset < d->vga.vram_size);
  1916. if (d->last_release_offset == 0) {
  1917. d->last_release = NULL;
  1918. } else {
  1919. d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);
  1920. }
  1921. d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);
  1922. trace_qxl_post_load(d->id, qxl_mode_to_string(d->mode));
  1923. newmode = d->mode;
  1924. d->mode = QXL_MODE_UNDEFINED;
  1925. switch (newmode) {
  1926. case QXL_MODE_UNDEFINED:
  1927. qxl_create_memslots(d);
  1928. break;
  1929. case QXL_MODE_VGA:
  1930. qxl_create_memslots(d);
  1931. qxl_enter_vga_mode(d);
  1932. break;
  1933. case QXL_MODE_NATIVE:
  1934. qxl_create_memslots(d);
  1935. qxl_create_guest_primary(d, 1, QXL_SYNC);
  1936. /* replay surface-create and cursor-set commands */
  1937. cmds = g_malloc0(sizeof(QXLCommandExt) * (d->ssd.num_surfaces + 1));
  1938. for (in = 0, out = 0; in < d->ssd.num_surfaces; in++) {
  1939. if (d->guest_surfaces.cmds[in] == 0) {
  1940. continue;
  1941. }
  1942. cmds[out].cmd.data = d->guest_surfaces.cmds[in];
  1943. cmds[out].cmd.type = QXL_CMD_SURFACE;
  1944. cmds[out].group_id = MEMSLOT_GROUP_GUEST;
  1945. out++;
  1946. }
  1947. if (d->guest_cursor) {
  1948. cmds[out].cmd.data = d->guest_cursor;
  1949. cmds[out].cmd.type = QXL_CMD_CURSOR;
  1950. cmds[out].group_id = MEMSLOT_GROUP_GUEST;
  1951. out++;
  1952. }
  1953. qxl_spice_loadvm_commands(d, cmds, out);
  1954. g_free(cmds);
  1955. if (d->guest_monitors_config) {
  1956. qxl_spice_monitors_config_async(d, 1);
  1957. }
  1958. break;
  1959. case QXL_MODE_COMPAT:
  1960. /* note: no need to call qxl_create_memslots, qxl_set_mode
  1961. * creates the mem slot. */
  1962. qxl_set_mode(d, d->shadow_rom.mode, 1);
  1963. break;
  1964. }
  1965. return 0;
  1966. }
  1967. #define QXL_SAVE_VERSION 21
  1968. static bool qxl_monitors_config_needed(void *opaque)
  1969. {
  1970. PCIQXLDevice *qxl = opaque;
  1971. return qxl->guest_monitors_config != 0;
  1972. }
  1973. static VMStateDescription qxl_memslot = {
  1974. .name = "qxl-memslot",
  1975. .version_id = QXL_SAVE_VERSION,
  1976. .minimum_version_id = QXL_SAVE_VERSION,
  1977. .fields = (VMStateField[]) {
  1978. VMSTATE_UINT64(slot.mem_start, struct guest_slots),
  1979. VMSTATE_UINT64(slot.mem_end, struct guest_slots),
  1980. VMSTATE_UINT32(active, struct guest_slots),
  1981. VMSTATE_END_OF_LIST()
  1982. }
  1983. };
  1984. static VMStateDescription qxl_surface = {
  1985. .name = "qxl-surface",
  1986. .version_id = QXL_SAVE_VERSION,
  1987. .minimum_version_id = QXL_SAVE_VERSION,
  1988. .fields = (VMStateField[]) {
  1989. VMSTATE_UINT32(width, QXLSurfaceCreate),
  1990. VMSTATE_UINT32(height, QXLSurfaceCreate),
  1991. VMSTATE_INT32(stride, QXLSurfaceCreate),
  1992. VMSTATE_UINT32(format, QXLSurfaceCreate),
  1993. VMSTATE_UINT32(position, QXLSurfaceCreate),
  1994. VMSTATE_UINT32(mouse_mode, QXLSurfaceCreate),
  1995. VMSTATE_UINT32(flags, QXLSurfaceCreate),
  1996. VMSTATE_UINT32(type, QXLSurfaceCreate),
  1997. VMSTATE_UINT64(mem, QXLSurfaceCreate),
  1998. VMSTATE_END_OF_LIST()
  1999. }
  2000. };
  2001. static VMStateDescription qxl_vmstate_monitors_config = {
  2002. .name = "qxl/monitors-config",
  2003. .version_id = 1,
  2004. .minimum_version_id = 1,
  2005. .fields = (VMStateField[]) {
  2006. VMSTATE_UINT64(guest_monitors_config, PCIQXLDevice),
  2007. VMSTATE_END_OF_LIST()
  2008. },
  2009. };
  2010. static VMStateDescription qxl_vmstate = {
  2011. .name = "qxl",
  2012. .version_id = QXL_SAVE_VERSION,
  2013. .minimum_version_id = QXL_SAVE_VERSION,
  2014. .pre_save = qxl_pre_save,
  2015. .pre_load = qxl_pre_load,
  2016. .post_load = qxl_post_load,
  2017. .fields = (VMStateField[]) {
  2018. VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
  2019. VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
  2020. VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
  2021. VMSTATE_UINT32(num_free_res, PCIQXLDevice),
  2022. VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
  2023. VMSTATE_UINT32(mode, PCIQXLDevice),
  2024. VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
  2025. VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
  2026. VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
  2027. qxl_memslot, struct guest_slots),
  2028. VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
  2029. qxl_surface, QXLSurfaceCreate),
  2030. VMSTATE_INT32_EQUAL(ssd.num_surfaces, PCIQXLDevice),
  2031. VMSTATE_VARRAY_INT32(guest_surfaces.cmds, PCIQXLDevice,
  2032. ssd.num_surfaces, 0,
  2033. vmstate_info_uint64, uint64_t),
  2034. VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
  2035. VMSTATE_END_OF_LIST()
  2036. },
  2037. .subsections = (VMStateSubsection[]) {
  2038. {
  2039. .vmsd = &qxl_vmstate_monitors_config,
  2040. .needed = qxl_monitors_config_needed,
  2041. }, {
  2042. /* empty */
  2043. }
  2044. }
  2045. };
  2046. static Property qxl_properties[] = {
  2047. DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
  2048. 64 * 1024 * 1024),
  2049. DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size,
  2050. 64 * 1024 * 1024),
  2051. DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
  2052. QXL_DEFAULT_REVISION),
  2053. DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
  2054. DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
  2055. DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
  2056. DEFINE_PROP_UINT32("ram_size_mb", PCIQXLDevice, ram_size_mb, -1),
  2057. DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1),
  2058. DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
  2059. DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
  2060. DEFINE_PROP_INT32("surfaces", PCIQXLDevice, ssd.num_surfaces, 1024),
  2061. DEFINE_PROP_END_OF_LIST(),
  2062. };
  2063. static void qxl_primary_class_init(ObjectClass *klass, void *data)
  2064. {
  2065. DeviceClass *dc = DEVICE_CLASS(klass);
  2066. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  2067. k->init = qxl_init_primary;
  2068. k->romfile = "vgabios-qxl.bin";
  2069. k->vendor_id = REDHAT_PCI_VENDOR_ID;
  2070. k->device_id = QXL_DEVICE_ID_STABLE;
  2071. k->class_id = PCI_CLASS_DISPLAY_VGA;
  2072. set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
  2073. dc->desc = "Spice QXL GPU (primary, vga compatible)";
  2074. dc->reset = qxl_reset_handler;
  2075. dc->vmsd = &qxl_vmstate;
  2076. dc->props = qxl_properties;
  2077. dc->hotpluggable = false;
  2078. }
  2079. static const TypeInfo qxl_primary_info = {
  2080. .name = "qxl-vga",
  2081. .parent = TYPE_PCI_DEVICE,
  2082. .instance_size = sizeof(PCIQXLDevice),
  2083. .class_init = qxl_primary_class_init,
  2084. };
  2085. static void qxl_secondary_class_init(ObjectClass *klass, void *data)
  2086. {
  2087. DeviceClass *dc = DEVICE_CLASS(klass);
  2088. PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  2089. k->init = qxl_init_secondary;
  2090. k->vendor_id = REDHAT_PCI_VENDOR_ID;
  2091. k->device_id = QXL_DEVICE_ID_STABLE;
  2092. k->class_id = PCI_CLASS_DISPLAY_OTHER;
  2093. set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
  2094. dc->desc = "Spice QXL GPU (secondary)";
  2095. dc->reset = qxl_reset_handler;
  2096. dc->vmsd = &qxl_vmstate;
  2097. dc->props = qxl_properties;
  2098. }
  2099. static const TypeInfo qxl_secondary_info = {
  2100. .name = "qxl",
  2101. .parent = TYPE_PCI_DEVICE,
  2102. .instance_size = sizeof(PCIQXLDevice),
  2103. .class_init = qxl_secondary_class_init,
  2104. };
  2105. static void qxl_register_types(void)
  2106. {
  2107. type_register_static(&qxl_primary_info);
  2108. type_register_static(&qxl_secondary_info);
  2109. }
  2110. type_init(qxl_register_types)