0210-vchiq_arm-Access-the-dequeue_pending-flag-locked.patch 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. From c2d672f4a69716b0619162a9fd99e3daf5b7406c Mon Sep 17 00:00:00 2001
  2. From: Phil Elwell <phil@raspberrypi.org>
  3. Date: Wed, 23 Mar 2016 14:16:25 +0000
  4. Subject: [PATCH] vchiq_arm: Access the dequeue_pending flag locked
  5. Reading through this code looking for another problem (now found in userland)
  6. the use of dequeue_pending outside a lock didn't seem safe.
  7. Signed-off-by: Phil Elwell <phil@raspberrypi.org>
  8. ---
  9. .../misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 17 ++++++++++++-----
  10. 1 file changed, 12 insertions(+), 5 deletions(-)
  11. --- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
  12. +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
  13. @@ -279,6 +279,7 @@ service_callback(VCHIQ_REASON_T reason,
  14. USER_SERVICE_T *user_service;
  15. VCHIQ_SERVICE_T *service;
  16. VCHIQ_INSTANCE_T instance;
  17. + int skip_completion = 0;
  18. DEBUG_INITIALISE(g_state.local)
  19. DEBUG_TRACE(SERVICE_CALLBACK_LINE);
  20. @@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason,
  21. user_service->msg_queue[user_service->msg_insert &
  22. (MSG_QUEUE_SIZE - 1)] = header;
  23. user_service->msg_insert++;
  24. - spin_unlock(&msg_queue_spinlock);
  25. -
  26. - up(&user_service->insert_event);
  27. /* If there is a thread waiting in DEQUEUE_MESSAGE, or if
  28. ** there is a MESSAGE_AVAILABLE in the completion queue then
  29. @@ -356,13 +354,22 @@ service_callback(VCHIQ_REASON_T reason,
  30. if (((user_service->message_available_pos -
  31. instance->completion_remove) >= 0) ||
  32. user_service->dequeue_pending) {
  33. - DEBUG_TRACE(SERVICE_CALLBACK_LINE);
  34. user_service->dequeue_pending = 0;
  35. - return VCHIQ_SUCCESS;
  36. + skip_completion = 1;
  37. }
  38. + spin_unlock(&msg_queue_spinlock);
  39. +
  40. + up(&user_service->insert_event);
  41. +
  42. header = NULL;
  43. }
  44. +
  45. + if (skip_completion) {
  46. + DEBUG_TRACE(SERVICE_CALLBACK_LINE);
  47. + return VCHIQ_SUCCESS;
  48. + }
  49. +
  50. DEBUG_TRACE(SERVICE_CALLBACK_LINE);
  51. return add_completion(instance, reason, header, user_service,