i915 driver fails on i686 userspace + x86_64 kernel

Pavel Roskin proski at gnu.org
Sun Oct 13 06:40:10 CEST 2013


Quoting Chris Wilson <chris at chris-wilson.co.uk>:

>> I believe the error is on the kernel side.  The kernel should
>> convert the pointer.  compat_ptr() doesn't convert the value, only
>> the type.  The comment in arch/x86/include/asm/compat.h says:
>
> That seems odd as the kernel expects a 32-bit address for the user
> process here.

I guess I was mislead by that comment.  I could not find any  
information how a x86_64 kernel sees the userspace memory of a 32-bit  
process.

> Can you please attach a dmesg with drm.debug=7 and
> --enable-debug=full Xorg.0.log?

I won't see that system until Tuesday.  I'll give you the information  
you ask, I'm just trying to understand the debugging data I have  
already.

I know from strace that DRM_IOCTL_MODE_GETENCODER fails with -EINVAL.   
I know from the debug printk in the kernel that drm_mode_getencoder()  
gets 0 as the encoder ID and that's why it returns -EINVAL.

I know from the Xorg intel driver (I got the git master version of it,  
recompiled it and got the same problem) that  
DRM_IOCTL_MODE_GETCONNECTOR is called immediately before  
DRM_IOCTL_MODE_GETENCODER in sna_output_init(), and that's the only  
place where DRM_IOCTL_MODE_GETENCODER is called.

I know that the last call to drm_mode_getconnector() before  
drm_mode_getencoder() copies exactly one encoder ID to the address  
provided by the user.  The address is something like 0xfnnnnnnn, i.e.  
it's a 32-bit address at the end of the first 4Gb of memory.  The  
system has 16Gb.  I understand it's an address on stack of the 32-bit  
Xorg process.

put_user() doesn't fail, or drm_mode_getconnector() would return  
-EFAULT, and I know that it returns 0.

The logic in drm_mode_getconnector() is such that encoder IDs are  
copied last and if the encoder ID is zero, it's not copied.  So I  
don't see how the kernel could overwrite that value.  However, gcc  
could reorder something, but I doubt it would reorder put_user()  
calls.  Anyway, I'll try to add buffers around enc in  
sna_output_init() to protect against memory corruption.

-- 
Regards,
Pavel Roskin


More information about the dri-devel mailing list