From e518c3ff34ac6805db6a234e0f1b990baac5bc5a Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 26 Aug 2014 09:22:20 +0100 Subject: 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 --- src/etnaviv/viv.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/etnaviv/viv.c b/src/etnaviv/viv.c index 67d41c9..b14341e 100644 --- a/src/etnaviv/viv.c +++ b/src/etnaviv/viv.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -113,7 +114,18 @@ 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. -- cgit