vmwgfx_execbuf.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  1. /**************************************************************************
  2. *
  3. * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  21. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  22. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  23. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  24. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. #include "vmwgfx_drv.h"
  28. #include "vmwgfx_reg.h"
  29. #include "ttm/ttm_bo_api.h"
  30. #include "ttm/ttm_placement.h"
  31. static int vmw_cmd_invalid(struct vmw_private *dev_priv,
  32. struct vmw_sw_context *sw_context,
  33. SVGA3dCmdHeader *header)
  34. {
  35. return capable(CAP_SYS_ADMIN) ? : -EINVAL;
  36. }
  37. static int vmw_cmd_ok(struct vmw_private *dev_priv,
  38. struct vmw_sw_context *sw_context,
  39. SVGA3dCmdHeader *header)
  40. {
  41. return 0;
  42. }
  43. static int vmw_resource_to_validate_list(struct vmw_sw_context *sw_context,
  44. struct vmw_resource **p_res)
  45. {
  46. int ret = 0;
  47. struct vmw_resource *res = *p_res;
  48. if (!res->on_validate_list) {
  49. if (sw_context->num_ref_resources >= VMWGFX_MAX_VALIDATIONS) {
  50. DRM_ERROR("Too many resources referenced in "
  51. "command stream.\n");
  52. ret = -ENOMEM;
  53. goto out;
  54. }
  55. sw_context->resources[sw_context->num_ref_resources++] = res;
  56. res->on_validate_list = true;
  57. return 0;
  58. }
  59. out:
  60. vmw_resource_unreference(p_res);
  61. return ret;
  62. }
  63. /**
  64. * vmw_bo_to_validate_list - add a bo to a validate list
  65. *
  66. * @sw_context: The software context used for this command submission batch.
  67. * @bo: The buffer object to add.
  68. * @fence_flags: Fence flags to be or'ed with any other fence flags for
  69. * this buffer on this submission batch.
  70. * @p_val_node: If non-NULL Will be updated with the validate node number
  71. * on return.
  72. *
  73. * Returns -EINVAL if the limit of number of buffer objects per command
  74. * submission is reached.
  75. */
  76. static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
  77. struct ttm_buffer_object *bo,
  78. uint32_t fence_flags,
  79. uint32_t *p_val_node)
  80. {
  81. uint32_t val_node;
  82. struct ttm_validate_buffer *val_buf;
  83. val_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf);
  84. if (unlikely(val_node >= VMWGFX_MAX_VALIDATIONS)) {
  85. DRM_ERROR("Max number of DMA buffers per submission"
  86. " exceeded.\n");
  87. return -EINVAL;
  88. }
  89. val_buf = &sw_context->val_bufs[val_node];
  90. if (unlikely(val_node == sw_context->cur_val_buf)) {
  91. val_buf->new_sync_obj_arg = NULL;
  92. val_buf->bo = ttm_bo_reference(bo);
  93. val_buf->usage = TTM_USAGE_READWRITE;
  94. list_add_tail(&val_buf->head, &sw_context->validate_nodes);
  95. ++sw_context->cur_val_buf;
  96. }
  97. val_buf->new_sync_obj_arg = (void *)
  98. ((unsigned long) val_buf->new_sync_obj_arg | fence_flags);
  99. sw_context->fence_flags |= fence_flags;
  100. if (p_val_node)
  101. *p_val_node = val_node;
  102. return 0;
  103. }
  104. static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
  105. struct vmw_sw_context *sw_context,
  106. SVGA3dCmdHeader *header)
  107. {
  108. struct vmw_resource *ctx;
  109. struct vmw_cid_cmd {
  110. SVGA3dCmdHeader header;
  111. __le32 cid;
  112. } *cmd;
  113. int ret;
  114. cmd = container_of(header, struct vmw_cid_cmd, header);
  115. if (likely(sw_context->cid_valid && cmd->cid == sw_context->last_cid))
  116. return 0;
  117. ret = vmw_context_check(dev_priv, sw_context->tfile, cmd->cid,
  118. &ctx);
  119. if (unlikely(ret != 0)) {
  120. DRM_ERROR("Could not find or use context %u\n",
  121. (unsigned) cmd->cid);
  122. return ret;
  123. }
  124. sw_context->last_cid = cmd->cid;
  125. sw_context->cid_valid = true;
  126. sw_context->cur_ctx = ctx;
  127. return vmw_resource_to_validate_list(sw_context, &ctx);
  128. }
  129. static int vmw_cmd_sid_check(struct vmw_private *dev_priv,
  130. struct vmw_sw_context *sw_context,
  131. uint32_t *sid)
  132. {
  133. struct vmw_surface *srf;
  134. int ret;
  135. struct vmw_resource *res;
  136. if (*sid == SVGA3D_INVALID_ID)
  137. return 0;
  138. if (likely((sw_context->sid_valid &&
  139. *sid == sw_context->last_sid))) {
  140. *sid = sw_context->sid_translation;
  141. return 0;
  142. }
  143. ret = vmw_user_surface_lookup_handle(dev_priv,
  144. sw_context->tfile,
  145. *sid, &srf);
  146. if (unlikely(ret != 0)) {
  147. DRM_ERROR("Could ot find or use surface 0x%08x "
  148. "address 0x%08lx\n",
  149. (unsigned int) *sid,
  150. (unsigned long) sid);
  151. return ret;
  152. }
  153. sw_context->last_sid = *sid;
  154. sw_context->sid_valid = true;
  155. sw_context->sid_translation = srf->res.id;
  156. *sid = sw_context->sid_translation;
  157. res = &srf->res;
  158. return vmw_resource_to_validate_list(sw_context, &res);
  159. }
  160. static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
  161. struct vmw_sw_context *sw_context,
  162. SVGA3dCmdHeader *header)
  163. {
  164. struct vmw_sid_cmd {
  165. SVGA3dCmdHeader header;
  166. SVGA3dCmdSetRenderTarget body;
  167. } *cmd;
  168. int ret;
  169. ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
  170. if (unlikely(ret != 0))
  171. return ret;
  172. cmd = container_of(header, struct vmw_sid_cmd, header);
  173. ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid);
  174. return ret;
  175. }
  176. static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
  177. struct vmw_sw_context *sw_context,
  178. SVGA3dCmdHeader *header)
  179. {
  180. struct vmw_sid_cmd {
  181. SVGA3dCmdHeader header;
  182. SVGA3dCmdSurfaceCopy body;
  183. } *cmd;
  184. int ret;
  185. cmd = container_of(header, struct vmw_sid_cmd, header);
  186. ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
  187. if (unlikely(ret != 0))
  188. return ret;
  189. return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
  190. }
  191. static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
  192. struct vmw_sw_context *sw_context,
  193. SVGA3dCmdHeader *header)
  194. {
  195. struct vmw_sid_cmd {
  196. SVGA3dCmdHeader header;
  197. SVGA3dCmdSurfaceStretchBlt body;
  198. } *cmd;
  199. int ret;
  200. cmd = container_of(header, struct vmw_sid_cmd, header);
  201. ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
  202. if (unlikely(ret != 0))
  203. return ret;
  204. return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
  205. }
  206. static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
  207. struct vmw_sw_context *sw_context,
  208. SVGA3dCmdHeader *header)
  209. {
  210. struct vmw_sid_cmd {
  211. SVGA3dCmdHeader header;
  212. SVGA3dCmdBlitSurfaceToScreen body;
  213. } *cmd;
  214. cmd = container_of(header, struct vmw_sid_cmd, header);
  215. if (unlikely(!sw_context->kernel)) {
  216. DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
  217. return -EPERM;
  218. }
  219. return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid);
  220. }
  221. static int vmw_cmd_present_check(struct vmw_private *dev_priv,
  222. struct vmw_sw_context *sw_context,
  223. SVGA3dCmdHeader *header)
  224. {
  225. struct vmw_sid_cmd {
  226. SVGA3dCmdHeader header;
  227. SVGA3dCmdPresent body;
  228. } *cmd;
  229. cmd = container_of(header, struct vmw_sid_cmd, header);
  230. if (unlikely(!sw_context->kernel)) {
  231. DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
  232. return -EPERM;
  233. }
  234. return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid);
  235. }
  236. /**
  237. * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries.
  238. *
  239. * @dev_priv: The device private structure.
  240. * @cid: The hardware context for the next query.
  241. * @new_query_bo: The new buffer holding query results.
  242. * @sw_context: The software context used for this command submission.
  243. *
  244. * This function checks whether @new_query_bo is suitable for holding
  245. * query results, and if another buffer currently is pinned for query
  246. * results. If so, the function prepares the state of @sw_context for
  247. * switching pinned buffers after successful submission of the current
  248. * command batch. It also checks whether we're using a new query context.
  249. * In that case, it makes sure we emit a query barrier for the old
  250. * context before the current query buffer is fenced.
  251. */
  252. static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
  253. uint32_t cid,
  254. struct ttm_buffer_object *new_query_bo,
  255. struct vmw_sw_context *sw_context)
  256. {
  257. int ret;
  258. bool add_cid = false;
  259. uint32_t cid_to_add;
  260. if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
  261. if (unlikely(new_query_bo->num_pages > 4)) {
  262. DRM_ERROR("Query buffer too large.\n");
  263. return -EINVAL;
  264. }
  265. if (unlikely(sw_context->cur_query_bo != NULL)) {
  266. BUG_ON(!sw_context->query_cid_valid);
  267. add_cid = true;
  268. cid_to_add = sw_context->cur_query_cid;
  269. ret = vmw_bo_to_validate_list(sw_context,
  270. sw_context->cur_query_bo,
  271. DRM_VMW_FENCE_FLAG_EXEC,
  272. NULL);
  273. if (unlikely(ret != 0))
  274. return ret;
  275. }
  276. sw_context->cur_query_bo = new_query_bo;
  277. ret = vmw_bo_to_validate_list(sw_context,
  278. dev_priv->dummy_query_bo,
  279. DRM_VMW_FENCE_FLAG_EXEC,
  280. NULL);
  281. if (unlikely(ret != 0))
  282. return ret;
  283. }
  284. if (unlikely(cid != sw_context->cur_query_cid &&
  285. sw_context->query_cid_valid)) {
  286. add_cid = true;
  287. cid_to_add = sw_context->cur_query_cid;
  288. }
  289. sw_context->cur_query_cid = cid;
  290. sw_context->query_cid_valid = true;
  291. if (add_cid) {
  292. struct vmw_resource *ctx = sw_context->cur_ctx;
  293. if (list_empty(&ctx->query_head))
  294. list_add_tail(&ctx->query_head,
  295. &sw_context->query_list);
  296. ret = vmw_bo_to_validate_list(sw_context,
  297. dev_priv->dummy_query_bo,
  298. DRM_VMW_FENCE_FLAG_EXEC,
  299. NULL);
  300. if (unlikely(ret != 0))
  301. return ret;
  302. }
  303. return 0;
  304. }
  305. /**
  306. * vmw_query_bo_switch_commit - Finalize switching pinned query buffer
  307. *
  308. * @dev_priv: The device private structure.
  309. * @sw_context: The software context used for this command submission batch.
  310. *
  311. * This function will check if we're switching query buffers, and will then,
  312. * if no other query waits are issued this command submission batch,
  313. * issue a dummy occlusion query wait used as a query barrier. When the fence
  314. * object following that query wait has signaled, we are sure that all
  315. * preseding queries have finished, and the old query buffer can be unpinned.
  316. * However, since both the new query buffer and the old one are fenced with
  317. * that fence, we can do an asynchronus unpin now, and be sure that the
  318. * old query buffer won't be moved until the fence has signaled.
  319. *
  320. * As mentioned above, both the new - and old query buffers need to be fenced
  321. * using a sequence emitted *after* calling this function.
  322. */
  323. static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
  324. struct vmw_sw_context *sw_context)
  325. {
  326. struct vmw_resource *ctx, *next_ctx;
  327. int ret;
  328. /*
  329. * The validate list should still hold references to all
  330. * contexts here.
  331. */
  332. list_for_each_entry_safe(ctx, next_ctx, &sw_context->query_list,
  333. query_head) {
  334. list_del_init(&ctx->query_head);
  335. BUG_ON(!ctx->on_validate_list);
  336. ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id);
  337. if (unlikely(ret != 0))
  338. DRM_ERROR("Out of fifo space for dummy query.\n");
  339. }
  340. if (dev_priv->pinned_bo != sw_context->cur_query_bo) {
  341. if (dev_priv->pinned_bo) {
  342. vmw_bo_pin(dev_priv->pinned_bo, false);
  343. ttm_bo_unref(&dev_priv->pinned_bo);
  344. }
  345. vmw_bo_pin(sw_context->cur_query_bo, true);
  346. /*
  347. * We pin also the dummy_query_bo buffer so that we
  348. * don't need to validate it when emitting
  349. * dummy queries in context destroy paths.
  350. */
  351. vmw_bo_pin(dev_priv->dummy_query_bo, true);
  352. dev_priv->dummy_query_bo_pinned = true;
  353. dev_priv->query_cid = sw_context->cur_query_cid;
  354. dev_priv->pinned_bo =
  355. ttm_bo_reference(sw_context->cur_query_bo);
  356. }
  357. }
  358. /**
  359. * vmw_query_switch_backoff - clear query barrier list
  360. * @sw_context: The sw context used for this submission batch.
  361. *
  362. * This function is used as part of an error path, where a previously
  363. * set up list of query barriers needs to be cleared.
  364. *
  365. */
  366. static void vmw_query_switch_backoff(struct vmw_sw_context *sw_context)
  367. {
  368. struct list_head *list, *next;
  369. list_for_each_safe(list, next, &sw_context->query_list) {
  370. list_del_init(list);
  371. }
  372. }
  373. static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
  374. struct vmw_sw_context *sw_context,
  375. SVGAGuestPtr *ptr,
  376. struct vmw_dma_buffer **vmw_bo_p)
  377. {
  378. struct vmw_dma_buffer *vmw_bo = NULL;
  379. struct ttm_buffer_object *bo;
  380. uint32_t handle = ptr->gmrId;
  381. struct vmw_relocation *reloc;
  382. int ret;
  383. ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
  384. if (unlikely(ret != 0)) {
  385. DRM_ERROR("Could not find or use GMR region.\n");
  386. return -EINVAL;
  387. }
  388. bo = &vmw_bo->base;
  389. if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
  390. DRM_ERROR("Max number relocations per submission"
  391. " exceeded\n");
  392. ret = -EINVAL;
  393. goto out_no_reloc;
  394. }
  395. reloc = &sw_context->relocs[sw_context->cur_reloc++];
  396. reloc->location = ptr;
  397. ret = vmw_bo_to_validate_list(sw_context, bo, DRM_VMW_FENCE_FLAG_EXEC,
  398. &reloc->index);
  399. if (unlikely(ret != 0))
  400. goto out_no_reloc;
  401. *vmw_bo_p = vmw_bo;
  402. return 0;
  403. out_no_reloc:
  404. vmw_dmabuf_unreference(&vmw_bo);
  405. vmw_bo_p = NULL;
  406. return ret;
  407. }
  408. static int vmw_cmd_end_query(struct vmw_private *dev_priv,
  409. struct vmw_sw_context *sw_context,
  410. SVGA3dCmdHeader *header)
  411. {
  412. struct vmw_dma_buffer *vmw_bo;
  413. struct vmw_query_cmd {
  414. SVGA3dCmdHeader header;
  415. SVGA3dCmdEndQuery q;
  416. } *cmd;
  417. int ret;
  418. cmd = container_of(header, struct vmw_query_cmd, header);
  419. ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
  420. if (unlikely(ret != 0))
  421. return ret;
  422. ret = vmw_translate_guest_ptr(dev_priv, sw_context,
  423. &cmd->q.guestResult,
  424. &vmw_bo);
  425. if (unlikely(ret != 0))
  426. return ret;
  427. ret = vmw_query_bo_switch_prepare(dev_priv, cmd->q.cid,
  428. &vmw_bo->base, sw_context);
  429. vmw_dmabuf_unreference(&vmw_bo);
  430. return ret;
  431. }
  432. static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
  433. struct vmw_sw_context *sw_context,
  434. SVGA3dCmdHeader *header)
  435. {
  436. struct vmw_dma_buffer *vmw_bo;
  437. struct vmw_query_cmd {
  438. SVGA3dCmdHeader header;
  439. SVGA3dCmdWaitForQuery q;
  440. } *cmd;
  441. int ret;
  442. struct vmw_resource *ctx;
  443. cmd = container_of(header, struct vmw_query_cmd, header);
  444. ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
  445. if (unlikely(ret != 0))
  446. return ret;
  447. ret = vmw_translate_guest_ptr(dev_priv, sw_context,
  448. &cmd->q.guestResult,
  449. &vmw_bo);
  450. if (unlikely(ret != 0))
  451. return ret;
  452. vmw_dmabuf_unreference(&vmw_bo);
  453. /*
  454. * This wait will act as a barrier for previous waits for this
  455. * context.
  456. */
  457. ctx = sw_context->cur_ctx;
  458. if (!list_empty(&ctx->query_head))
  459. list_del_init(&ctx->query_head);
  460. return 0;
  461. }
  462. static int vmw_cmd_dma(struct vmw_private *dev_priv,
  463. struct vmw_sw_context *sw_context,
  464. SVGA3dCmdHeader *header)
  465. {
  466. struct vmw_dma_buffer *vmw_bo = NULL;
  467. struct ttm_buffer_object *bo;
  468. struct vmw_surface *srf = NULL;
  469. struct vmw_dma_cmd {
  470. SVGA3dCmdHeader header;
  471. SVGA3dCmdSurfaceDMA dma;
  472. } *cmd;
  473. int ret;
  474. struct vmw_resource *res;
  475. cmd = container_of(header, struct vmw_dma_cmd, header);
  476. ret = vmw_translate_guest_ptr(dev_priv, sw_context,
  477. &cmd->dma.guest.ptr,
  478. &vmw_bo);
  479. if (unlikely(ret != 0))
  480. return ret;
  481. bo = &vmw_bo->base;
  482. ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile,
  483. cmd->dma.host.sid, &srf);
  484. if (ret) {
  485. DRM_ERROR("could not find surface\n");
  486. goto out_no_reloc;
  487. }
  488. /*
  489. * Patch command stream with device SID.
  490. */
  491. cmd->dma.host.sid = srf->res.id;
  492. vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header);
  493. vmw_dmabuf_unreference(&vmw_bo);
  494. res = &srf->res;
  495. return vmw_resource_to_validate_list(sw_context, &res);
  496. out_no_reloc:
  497. vmw_dmabuf_unreference(&vmw_bo);
  498. return ret;
  499. }
  500. static int vmw_cmd_draw(struct vmw_private *dev_priv,
  501. struct vmw_sw_context *sw_context,
  502. SVGA3dCmdHeader *header)
  503. {
  504. struct vmw_draw_cmd {
  505. SVGA3dCmdHeader header;
  506. SVGA3dCmdDrawPrimitives body;
  507. } *cmd;
  508. SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
  509. (unsigned long)header + sizeof(*cmd));
  510. SVGA3dPrimitiveRange *range;
  511. uint32_t i;
  512. uint32_t maxnum;
  513. int ret;
  514. ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
  515. if (unlikely(ret != 0))
  516. return ret;
  517. cmd = container_of(header, struct vmw_draw_cmd, header);
  518. maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
  519. if (unlikely(cmd->body.numVertexDecls > maxnum)) {
  520. DRM_ERROR("Illegal number of vertex declarations.\n");
  521. return -EINVAL;
  522. }
  523. for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
  524. ret = vmw_cmd_sid_check(dev_priv, sw_context,
  525. &decl->array.surfaceId);
  526. if (unlikely(ret != 0))
  527. return ret;
  528. }
  529. maxnum = (header->size - sizeof(cmd->body) -
  530. cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
  531. if (unlikely(cmd->body.numRanges > maxnum)) {
  532. DRM_ERROR("Illegal number of index ranges.\n");
  533. return -EINVAL;
  534. }
  535. range = (SVGA3dPrimitiveRange *) decl;
  536. for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
  537. ret = vmw_cmd_sid_check(dev_priv, sw_context,
  538. &range->indexArray.surfaceId);
  539. if (unlikely(ret != 0))
  540. return ret;
  541. }
  542. return 0;
  543. }
  544. static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
  545. struct vmw_sw_context *sw_context,
  546. SVGA3dCmdHeader *header)
  547. {
  548. struct vmw_tex_state_cmd {
  549. SVGA3dCmdHeader header;
  550. SVGA3dCmdSetTextureState state;
  551. };
  552. SVGA3dTextureState *last_state = (SVGA3dTextureState *)
  553. ((unsigned long) header + header->size + sizeof(header));
  554. SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
  555. ((unsigned long) header + sizeof(struct vmw_tex_state_cmd));
  556. int ret;
  557. ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
  558. if (unlikely(ret != 0))
  559. return ret;
  560. for (; cur_state < last_state; ++cur_state) {
  561. if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
  562. continue;
  563. ret = vmw_cmd_sid_check(dev_priv, sw_context,
  564. &cur_state->value);
  565. if (unlikely(ret != 0))
  566. return ret;
  567. }
  568. return 0;
  569. }
  570. static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
  571. struct vmw_sw_context *sw_context,
  572. void *buf)
  573. {
  574. struct vmw_dma_buffer *vmw_bo;
  575. int ret;
  576. struct {
  577. uint32_t header;
  578. SVGAFifoCmdDefineGMRFB body;
  579. } *cmd = buf;
  580. ret = vmw_translate_guest_ptr(dev_priv, sw_context,
  581. &cmd->body.ptr,
  582. &vmw_bo);
  583. if (unlikely(ret != 0))
  584. return ret;
  585. vmw_dmabuf_unreference(&vmw_bo);
  586. return ret;
  587. }
  588. static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
  589. struct vmw_sw_context *sw_context,
  590. void *buf, uint32_t *size)
  591. {
  592. uint32_t size_remaining = *size;
  593. uint32_t cmd_id;
  594. cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
  595. switch (cmd_id) {
  596. case SVGA_CMD_UPDATE:
  597. *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate);
  598. break;
  599. case SVGA_CMD_DEFINE_GMRFB:
  600. *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB);
  601. break;
  602. case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
  603. *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
  604. break;
  605. case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
  606. *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
  607. break;
  608. default:
  609. DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id);
  610. return -EINVAL;
  611. }
  612. if (*size > size_remaining) {
  613. DRM_ERROR("Invalid SVGA command (size mismatch):"
  614. " %u.\n", cmd_id);
  615. return -EINVAL;
  616. }
  617. if (unlikely(!sw_context->kernel)) {
  618. DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id);
  619. return -EPERM;
  620. }
  621. if (cmd_id == SVGA_CMD_DEFINE_GMRFB)
  622. return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf);
  623. return 0;
  624. }
  625. typedef int (*vmw_cmd_func) (struct vmw_private *,
  626. struct vmw_sw_context *,
  627. SVGA3dCmdHeader *);
  628. #define VMW_CMD_DEF(cmd, func) \
  629. [cmd - SVGA_3D_CMD_BASE] = func
  630. static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = {
  631. VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid),
  632. VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid),
  633. VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check),
  634. VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check),
  635. VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma),
  636. VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid),
  637. VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid),
  638. VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check),
  639. VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check),
  640. VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check),
  641. VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
  642. &vmw_cmd_set_render_target_check),
  643. VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state),
  644. VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check),
  645. VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check),
  646. VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check),
  647. VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check),
  648. VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check),
  649. VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check),
  650. VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check),
  651. VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check),
  652. VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check),
  653. VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check),
  654. VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check),
  655. VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw),
  656. VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check),
  657. VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check),
  658. VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query),
  659. VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query),
  660. VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok),
  661. VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
  662. &vmw_cmd_blt_surf_screen_check)
  663. };
  664. static int vmw_cmd_check(struct vmw_private *dev_priv,
  665. struct vmw_sw_context *sw_context,
  666. void *buf, uint32_t *size)
  667. {
  668. uint32_t cmd_id;
  669. uint32_t size_remaining = *size;
  670. SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
  671. int ret;
  672. cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
  673. /* Handle any none 3D commands */
  674. if (unlikely(cmd_id < SVGA_CMD_MAX))
  675. return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size);
  676. cmd_id = le32_to_cpu(header->id);
  677. *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader);
  678. cmd_id -= SVGA_3D_CMD_BASE;
  679. if (unlikely(*size > size_remaining))
  680. goto out_err;
  681. if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
  682. goto out_err;
  683. ret = vmw_cmd_funcs[cmd_id](dev_priv, sw_context, header);
  684. if (unlikely(ret != 0))
  685. goto out_err;
  686. return 0;
  687. out_err:
  688. DRM_ERROR("Illegal / Invalid SVGA3D command: %d\n",
  689. cmd_id + SVGA_3D_CMD_BASE);
  690. return -EINVAL;
  691. }
  692. static int vmw_cmd_check_all(struct vmw_private *dev_priv,
  693. struct vmw_sw_context *sw_context,
  694. void *buf,
  695. uint32_t size)
  696. {
  697. int32_t cur_size = size;
  698. int ret;
  699. while (cur_size > 0) {
  700. size = cur_size;
  701. ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
  702. if (unlikely(ret != 0))
  703. return ret;
  704. buf = (void *)((unsigned long) buf + size);
  705. cur_size -= size;
  706. }
  707. if (unlikely(cur_size != 0)) {
  708. DRM_ERROR("Command verifier out of sync.\n");
  709. return -EINVAL;
  710. }
  711. return 0;
  712. }
  713. static void vmw_free_relocations(struct vmw_sw_context *sw_context)
  714. {
  715. sw_context->cur_reloc = 0;
  716. }
  717. static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
  718. {
  719. uint32_t i;
  720. struct vmw_relocation *reloc;
  721. struct ttm_validate_buffer *validate;
  722. struct ttm_buffer_object *bo;
  723. for (i = 0; i < sw_context->cur_reloc; ++i) {
  724. reloc = &sw_context->relocs[i];
  725. validate = &sw_context->val_bufs[reloc->index];
  726. bo = validate->bo;
  727. if (bo->mem.mem_type == TTM_PL_VRAM) {
  728. reloc->location->offset += bo->offset;
  729. reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER;
  730. } else
  731. reloc->location->gmrId = bo->mem.start;
  732. }
  733. vmw_free_relocations(sw_context);
  734. }
  735. static void vmw_clear_validations(struct vmw_sw_context *sw_context)
  736. {
  737. struct ttm_validate_buffer *entry, *next;
  738. uint32_t i = sw_context->num_ref_resources;
  739. /*
  740. * Drop references to DMA buffers held during command submission.
  741. */
  742. list_for_each_entry_safe(entry, next, &sw_context->validate_nodes,
  743. head) {
  744. list_del(&entry->head);
  745. vmw_dmabuf_validate_clear(entry->bo);
  746. ttm_bo_unref(&entry->bo);
  747. sw_context->cur_val_buf--;
  748. }
  749. BUG_ON(sw_context->cur_val_buf != 0);
  750. /*
  751. * Drop references to resources held during command submission.
  752. */
  753. while (i-- > 0) {
  754. sw_context->resources[i]->on_validate_list = false;
  755. vmw_resource_unreference(&sw_context->resources[i]);
  756. }
  757. }
  758. static int vmw_validate_single_buffer(struct vmw_private *dev_priv,
  759. struct ttm_buffer_object *bo)
  760. {
  761. int ret;
  762. /*
  763. * Don't validate pinned buffers.
  764. */
  765. if (bo == dev_priv->pinned_bo ||
  766. (bo == dev_priv->dummy_query_bo &&
  767. dev_priv->dummy_query_bo_pinned))
  768. return 0;
  769. /**
  770. * Put BO in VRAM if there is space, otherwise as a GMR.
  771. * If there is no space in VRAM and GMR ids are all used up,
  772. * start evicting GMRs to make room. If the DMA buffer can't be
  773. * used as a GMR, this will return -ENOMEM.
  774. */
  775. ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, true, false, false);
  776. if (likely(ret == 0 || ret == -ERESTARTSYS))
  777. return ret;
  778. /**
  779. * If that failed, try VRAM again, this time evicting
  780. * previous contents.
  781. */
  782. DRM_INFO("Falling through to VRAM.\n");
  783. ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false, false);
  784. return ret;
  785. }
  786. static int vmw_validate_buffers(struct vmw_private *dev_priv,
  787. struct vmw_sw_context *sw_context)
  788. {
  789. struct ttm_validate_buffer *entry;
  790. int ret;
  791. list_for_each_entry(entry, &sw_context->validate_nodes, head) {
  792. ret = vmw_validate_single_buffer(dev_priv, entry->bo);
  793. if (unlikely(ret != 0))
  794. return ret;
  795. }
  796. return 0;
  797. }
  798. static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context,
  799. uint32_t size)
  800. {
  801. if (likely(sw_context->cmd_bounce_size >= size))
  802. return 0;
  803. if (sw_context->cmd_bounce_size == 0)
  804. sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE;
  805. while (sw_context->cmd_bounce_size < size) {
  806. sw_context->cmd_bounce_size =
  807. PAGE_ALIGN(sw_context->cmd_bounce_size +
  808. (sw_context->cmd_bounce_size >> 1));
  809. }
  810. if (sw_context->cmd_bounce != NULL)
  811. vfree(sw_context->cmd_bounce);
  812. sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size);
  813. if (sw_context->cmd_bounce == NULL) {
  814. DRM_ERROR("Failed to allocate command bounce buffer.\n");
  815. sw_context->cmd_bounce_size = 0;
  816. return -ENOMEM;
  817. }
  818. return 0;
  819. }
  820. /**
  821. * vmw_execbuf_fence_commands - create and submit a command stream fence
  822. *
  823. * Creates a fence object and submits a command stream marker.
  824. * If this fails for some reason, We sync the fifo and return NULL.
  825. * It is then safe to fence buffers with a NULL pointer.
  826. *
  827. * If @p_handle is not NULL @file_priv must also not be NULL. Creates
  828. * a userspace handle if @p_handle is not NULL, otherwise not.
  829. */
  830. int vmw_execbuf_fence_commands(struct drm_file *file_priv,
  831. struct vmw_private *dev_priv,
  832. struct vmw_fence_obj **p_fence,
  833. uint32_t *p_handle)
  834. {
  835. uint32_t sequence;
  836. int ret;
  837. bool synced = false;
  838. /* p_handle implies file_priv. */
  839. BUG_ON(p_handle != NULL && file_priv == NULL);
  840. ret = vmw_fifo_send_fence(dev_priv, &sequence);
  841. if (unlikely(ret != 0)) {
  842. DRM_ERROR("Fence submission error. Syncing.\n");
  843. synced = true;
  844. }
  845. if (p_handle != NULL)
  846. ret = vmw_user_fence_create(file_priv, dev_priv->fman,
  847. sequence,
  848. DRM_VMW_FENCE_FLAG_EXEC,
  849. p_fence, p_handle);
  850. else
  851. ret = vmw_fence_create(dev_priv->fman, sequence,
  852. DRM_VMW_FENCE_FLAG_EXEC,
  853. p_fence);
  854. if (unlikely(ret != 0 && !synced)) {
  855. (void) vmw_fallback_wait(dev_priv, false, false,
  856. sequence, false,
  857. VMW_FENCE_WAIT_TIMEOUT);
  858. *p_fence = NULL;
  859. }
  860. return 0;
  861. }
  862. int vmw_execbuf_process(struct drm_file *file_priv,
  863. struct vmw_private *dev_priv,
  864. void __user *user_commands,
  865. void *kernel_commands,
  866. uint32_t command_size,
  867. uint64_t throttle_us,
  868. struct drm_vmw_fence_rep __user *user_fence_rep)
  869. {
  870. struct vmw_sw_context *sw_context = &dev_priv->ctx;
  871. struct drm_vmw_fence_rep fence_rep;
  872. struct vmw_fence_obj *fence;
  873. uint32_t handle;
  874. void *cmd;
  875. int ret;
  876. ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
  877. if (unlikely(ret != 0))
  878. return -ERESTARTSYS;
  879. if (kernel_commands == NULL) {
  880. sw_context->kernel = false;
  881. ret = vmw_resize_cmd_bounce(sw_context, command_size);
  882. if (unlikely(ret != 0))
  883. goto out_unlock;
  884. ret = copy_from_user(sw_context->cmd_bounce,
  885. user_commands, command_size);
  886. if (unlikely(ret != 0)) {
  887. ret = -EFAULT;
  888. DRM_ERROR("Failed copying commands.\n");
  889. goto out_unlock;
  890. }
  891. kernel_commands = sw_context->cmd_bounce;
  892. } else
  893. sw_context->kernel = true;
  894. sw_context->tfile = vmw_fpriv(file_priv)->tfile;
  895. sw_context->cid_valid = false;
  896. sw_context->sid_valid = false;
  897. sw_context->cur_reloc = 0;
  898. sw_context->cur_val_buf = 0;
  899. sw_context->num_ref_resources = 0;
  900. sw_context->fence_flags = 0;
  901. INIT_LIST_HEAD(&sw_context->query_list);
  902. sw_context->cur_query_bo = dev_priv->pinned_bo;
  903. sw_context->cur_query_cid = dev_priv->query_cid;
  904. sw_context->query_cid_valid = (dev_priv->pinned_bo != NULL);
  905. INIT_LIST_HEAD(&sw_context->validate_nodes);
  906. ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
  907. command_size);
  908. if (unlikely(ret != 0))
  909. goto out_err;
  910. ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes);
  911. if (unlikely(ret != 0))
  912. goto out_err;
  913. ret = vmw_validate_buffers(dev_priv, sw_context);
  914. if (unlikely(ret != 0))
  915. goto out_err;
  916. vmw_apply_relocations(sw_context);
  917. if (throttle_us) {
  918. ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
  919. throttle_us);
  920. if (unlikely(ret != 0))
  921. goto out_throttle;
  922. }
  923. cmd = vmw_fifo_reserve(dev_priv, command_size);
  924. if (unlikely(cmd == NULL)) {
  925. DRM_ERROR("Failed reserving fifo space for commands.\n");
  926. ret = -ENOMEM;
  927. goto out_throttle;
  928. }
  929. memcpy(cmd, kernel_commands, command_size);
  930. vmw_fifo_commit(dev_priv, command_size);
  931. vmw_query_bo_switch_commit(dev_priv, sw_context);
  932. ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
  933. &fence,
  934. (user_fence_rep) ? &handle : NULL);
  935. /*
  936. * This error is harmless, because if fence submission fails,
  937. * vmw_fifo_send_fence will sync. The error will be propagated to
  938. * user-space in @fence_rep
  939. */
  940. if (ret != 0)
  941. DRM_ERROR("Fence submission error. Syncing.\n");
  942. ttm_eu_fence_buffer_objects(&sw_context->validate_nodes,
  943. (void *) fence);
  944. vmw_clear_validations(sw_context);
  945. if (user_fence_rep) {
  946. fence_rep.error = ret;
  947. fence_rep.handle = handle;
  948. fence_rep.seqno = fence->seqno;
  949. vmw_update_seqno(dev_priv, &dev_priv->fifo);
  950. fence_rep.passed_seqno = dev_priv->last_read_seqno;
  951. /*
  952. * copy_to_user errors will be detected by user space not
  953. * seeing fence_rep::error filled in. Typically
  954. * user-space would have pre-set that member to -EFAULT.
  955. */
  956. ret = copy_to_user(user_fence_rep, &fence_rep,
  957. sizeof(fence_rep));
  958. /*
  959. * User-space lost the fence object. We need to sync
  960. * and unreference the handle.
  961. */
  962. if (unlikely(ret != 0) && (fence_rep.error == 0)) {
  963. BUG_ON(fence == NULL);
  964. ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
  965. handle, TTM_REF_USAGE);
  966. DRM_ERROR("Fence copy error. Syncing.\n");
  967. (void) vmw_fence_obj_wait(fence,
  968. fence->signal_mask,
  969. false, false,
  970. VMW_FENCE_WAIT_TIMEOUT);
  971. }
  972. }
  973. if (likely(fence != NULL))
  974. vmw_fence_obj_unreference(&fence);
  975. mutex_unlock(&dev_priv->cmdbuf_mutex);
  976. return 0;
  977. out_err:
  978. vmw_free_relocations(sw_context);
  979. out_throttle:
  980. vmw_query_switch_backoff(sw_context);
  981. ttm_eu_backoff_reservation(&sw_context->validate_nodes);
  982. vmw_clear_validations(sw_context);
  983. out_unlock:
  984. mutex_unlock(&dev_priv->cmdbuf_mutex);
  985. return ret;
  986. }
  987. /**
  988. * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
  989. *
  990. * @dev_priv: The device private structure.
  991. *
  992. * This function is called to idle the fifo and unpin the query buffer
  993. * if the normal way to do this hits an error, which should typically be
  994. * extremely rare.
  995. */
  996. static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv)
  997. {
  998. DRM_ERROR("Can't unpin query buffer. Trying to recover.\n");
  999. (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ);
  1000. vmw_bo_pin(dev_priv->pinned_bo, false);
  1001. vmw_bo_pin(dev_priv->dummy_query_bo, false);
  1002. dev_priv->dummy_query_bo_pinned = false;
  1003. }
  1004. /**
  1005. * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
  1006. * query bo.
  1007. *
  1008. * @dev_priv: The device private structure.
  1009. * @only_on_cid_match: Only flush and unpin if the current active query cid
  1010. * matches @cid.
  1011. * @cid: Optional context id to match.
  1012. *
  1013. * This function should be used to unpin the pinned query bo, or
  1014. * as a query barrier when we need to make sure that all queries have
  1015. * finished before the next fifo command. (For example on hardware
  1016. * context destructions where the hardware may otherwise leak unfinished
  1017. * queries).
  1018. *
  1019. * This function does not return any failure codes, but make attempts
  1020. * to do safe unpinning in case of errors.
  1021. *
  1022. * The function will synchronize on the previous query barrier, and will
  1023. * thus not finish until that barrier has executed.
  1024. */
  1025. void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
  1026. bool only_on_cid_match, uint32_t cid)
  1027. {
  1028. int ret = 0;
  1029. struct list_head validate_list;
  1030. struct ttm_validate_buffer pinned_val, query_val;
  1031. struct vmw_fence_obj *fence;
  1032. mutex_lock(&dev_priv->cmdbuf_mutex);
  1033. if (dev_priv->pinned_bo == NULL)
  1034. goto out_unlock;
  1035. if (only_on_cid_match && cid != dev_priv->query_cid)
  1036. goto out_unlock;
  1037. INIT_LIST_HEAD(&validate_list);
  1038. pinned_val.new_sync_obj_arg = (void *)(unsigned long)
  1039. DRM_VMW_FENCE_FLAG_EXEC;
  1040. pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo);
  1041. list_add_tail(&pinned_val.head, &validate_list);
  1042. query_val.new_sync_obj_arg = pinned_val.new_sync_obj_arg;
  1043. query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo);
  1044. list_add_tail(&query_val.head, &validate_list);
  1045. do {
  1046. ret = ttm_eu_reserve_buffers(&validate_list);
  1047. } while (ret == -ERESTARTSYS);
  1048. if (unlikely(ret != 0)) {
  1049. vmw_execbuf_unpin_panic(dev_priv);
  1050. goto out_no_reserve;
  1051. }
  1052. ret = vmw_fifo_emit_dummy_query(dev_priv, dev_priv->query_cid);
  1053. if (unlikely(ret != 0)) {
  1054. vmw_execbuf_unpin_panic(dev_priv);
  1055. goto out_no_emit;
  1056. }
  1057. vmw_bo_pin(dev_priv->pinned_bo, false);
  1058. vmw_bo_pin(dev_priv->dummy_query_bo, false);
  1059. dev_priv->dummy_query_bo_pinned = false;
  1060. (void) vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
  1061. ttm_eu_fence_buffer_objects(&validate_list, (void *) fence);
  1062. ttm_bo_unref(&query_val.bo);
  1063. ttm_bo_unref(&pinned_val.bo);
  1064. ttm_bo_unref(&dev_priv->pinned_bo);
  1065. out_unlock:
  1066. mutex_unlock(&dev_priv->cmdbuf_mutex);
  1067. return;
  1068. out_no_emit:
  1069. ttm_eu_backoff_reservation(&validate_list);
  1070. out_no_reserve:
  1071. ttm_bo_unref(&query_val.bo);
  1072. ttm_bo_unref(&pinned_val.bo);
  1073. ttm_bo_unref(&dev_priv->pinned_bo);
  1074. mutex_unlock(&dev_priv->cmdbuf_mutex);
  1075. }
  1076. int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
  1077. struct drm_file *file_priv)
  1078. {
  1079. struct vmw_private *dev_priv = vmw_priv(dev);
  1080. struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data;
  1081. struct vmw_master *vmaster = vmw_master(file_priv->master);
  1082. int ret;
  1083. /*
  1084. * This will allow us to extend the ioctl argument while
  1085. * maintaining backwards compatibility:
  1086. * We take different code paths depending on the value of
  1087. * arg->version.
  1088. */
  1089. if (unlikely(arg->version != DRM_VMW_EXECBUF_VERSION)) {
  1090. DRM_ERROR("Incorrect execbuf version.\n");
  1091. DRM_ERROR("You're running outdated experimental "
  1092. "vmwgfx user-space drivers.");
  1093. return -EINVAL;
  1094. }
  1095. ret = ttm_read_lock(&vmaster->lock, true);
  1096. if (unlikely(ret != 0))
  1097. return ret;
  1098. ret = vmw_execbuf_process(file_priv, dev_priv,
  1099. (void __user *)(unsigned long)arg->commands,
  1100. NULL, arg->command_size, arg->throttle_us,
  1101. (void __user *)(unsigned long)arg->fence_rep);
  1102. if (unlikely(ret != 0))
  1103. goto out_unlock;
  1104. vmw_kms_cursor_post_execbuf(dev_priv);
  1105. out_unlock:
  1106. ttm_read_unlock(&vmaster->lock);
  1107. return ret;
  1108. }