summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2014-08-26 09:22:20 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-08-27 09:01:26 +0200
commit5fa8a35296c80f2b37888adabf68e0e3b995e865 (patch)
tree9875e0364dde8faa37ee84c6ded529d05d5854b0
parent2a28d1d9dda5a45ca8cf67e25151733e30f30165 (diff)
downloadetna_viv-5fa8a35296c80f2b37888adabf68e0e3b995e865.tar.gz
etna_viv-5fa8a35296c80f2b37888adabf68e0e3b995e865.tar.xz
Properly handle ioctl() returning EINTR
Jon Nettleton's kernel galcore driver can return EINTR while waiting for user signals. With this galcore version, if we are waiting on a command buffer galcore signal (to indicate that the buffer is now available for re-use), and we are sent a user signal (eg, SIGALRM), then ioctl() may return EINTR. This causes etnaviv to believe that the galcore signal was received, and it is safe to proceed with the next command buffer. In reality, this can cause the GPU to scribble over memory which it should not, and can cause the entire platform to lock up. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--src/etnaviv/viv.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/etnaviv/viv.c b/src/etnaviv/viv.c
index 13504b5..f7ca6b2 100644
--- a/src/etnaviv/viv.c
+++ b/src/etnaviv/viv.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -113,7 +114,18 @@ static int viv_ioctl(struct viv_conn *conn, int request, void *data, size_t size
.out_buf_size = size
#endif
};
- return ioctl(conn->fd, request, &ic);
+ int ret, old_errno = errno;
+
+ do {
+ errno = 0;
+ ret = ioctl(conn->fd, request, &ic);
+ } while (ret == -1 && errno == EINTR);
+
+ /* if there was no error, restore the old errno for proper errno handling */
+ if(errno == 0)
+ errno = old_errno;
+
+ return ret;
}
/* Call ioctl interface with structure cmd as input and output.