etnaviv MMU fault and memory corruption caused by bogus glVertexAttribPointer() arguments
Tracing an annoying hang and MMU faults in telegram-desktop (when viewing media) on imx8mq/GC7000 rev 6124, I found that something related to glVertexAttribPointer() is the culprit.
Mesa is latest from git (OpenGL version string: 2.1 Mesa 23.1.0-devel (git-17b610771d)
), Kernel is 6.1.7.
I hacked together a minimal test program which reproduces the issue:
// Minimal OpenGL shader example using OpenGL directly
#include <math.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>
GLuint vao;
GLuint vbo;
GLuint idx;
GLuint tex;
GLuint program;
int width = 320;
int height = 240;
void onDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void
*)0);
glutSwapBuffers();
}
void onResize(int w, int h)
{
width = w; height = h;
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
}
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f
};
unsigned int indices[] = { 0, 1, 2 };
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutCreateWindow("mini");
glewExperimental = GL_TRUE;
glewInit();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &idx);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// invalid last parameter
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *)0xffff);
glEnableVertexAttribArray(0);
glutDisplayFunc(onDisplay);
glutReshapeFunc(onResize);
glutMainLoop();
glDisableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &idx);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
return 0;
}
The program is compiled with gcc -o test test.c -lGL -lGLEW -lGLU -lglut
.
Executing it causes kernel messages like:
[ 5480.472043] etnaviv-gpu 38000000.gpu: MMU fault status 0x00000001
[ 5480.478161] etnaviv-gpu 38000000.gpu: MMU 0 fault addr 0xfd4baf00
[ 5481.490650] etnaviv-gpu 38000000.gpu: recover hung GPU!
[ 5604.120350] Huh VM_FAULT_OOM leaked out to the #PF handler. Retrying PF
[ 5779.887180] Huh VM_FAULT_OOM leaked out to the #PF handler. Retrying PF
[ 5780.176308] Huh VM_FAULT_OOM leaked out to the #PF handler. Retrying PF
Changing the first and last arguments to glVertexAttribPointer() causes other severe effects. For example, with the first parameter as -1 and the last as 0, textures of other programs (under sway) are trashed or disappear. It is also possible to completely hang the machine.