Re: [PATCH] Revert "x86/uaccess: Add stack frame output operand in get_user() inline asm"

From: Matthias Kaehlcke
Date: Wed Jul 12 2017 - 19:22:25 EST


El Wed, Jul 12, 2017 at 05:36:30PM -0500 Josh Poimboeuf ha dit:

> On Wed, Jul 12, 2017 at 05:35:47PM -0500, Josh Poimboeuf wrote:
> > On Wed, Jul 12, 2017 at 03:20:40PM -0700, Matthias Kaehlcke wrote:
> > > > This is admittedly an awkward way of achieving this goal, but it's the
> > > > only way I know how to do it with GCC.
> > > >
> > > > What extra instruction does clang add?
> > >
> > > I was looking at the get_user() call in drm_mode_setcrtc(). The code
> > > generated by clang without the patch is:
> > >
> > > if (get_user(out_id, &set_connectors_ptr[i])) {
> > > ffffffff81386955: 4a 8d 04 bd 00 00 00 lea 0x0(,%r15,4),%rax
> > > ffffffff8138695c: 00
> > > ffffffff8138695d: 49 03 06 add (%r14),%rax
> > > ffffffff81386960: e8 2b a5 f0 ff callq ffffffff81290e90 <__get_user_4>
> > >
> > > And with the patch:
> > >
> > > if (get_user(out_id, &set_connectors_ptr[i])) {
> > > ffffffff81386a56: 4a 8d 04 bd 00 00 00 lea 0x0(,%r15,4),%rax
> > > ffffffff81386a5d: 00
> > > ffffffff81386a5e: 49 03 06 add (%r14),%rax
> > > ffffffff81386a61: 48 8b 64 24 28 mov 0x28(%rsp),%rsp
> > > ffffffff81386a66: e8 15 a5 f0 ff callq
> > > ffffffff81290f80 <__get_user_4>
> >
> > Hm, that seems odd. Can you sure the disassembly for the whole
> > function?
>
> Er, share :-)

Sure, please find below the disassemblies with and without the
patch. The exact extra instruction differs from the one above, the
disassembly above is from a debug session with some 'random' kernel
version (bisect), the ones below from a v4.12ish kernel. At the bottom
you also find a log of a double faults observed with the patch.

If you are interested in building the kernel with clang yourself I can
provide instructions, it is fairly painless nowadays as long as you
have a recent version of clang (a somewhat older version should also
do for this issue with some extra kernel patches).

With f05058c4d652:

ffffffff81367550 <drm_mode_setcrtc>:
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
ffffffff81367550: e8 db 71 2e 00 callq ffffffff8164e730 <__fentry__>
ffffffff81367555: 55 push %rbp
ffffffff81367556: 48 89 e5 mov %rsp,%rbp
ffffffff81367559: 41 57 push %r15
ffffffff8136755b: 41 56 push %r14
ffffffff8136755d: 41 55 push %r13
ffffffff8136755f: 41 54 push %r12
ffffffff81367561: 53 push %rbx
ffffffff81367562: 48 81 ec c0 00 00 00 sub $0xc0,%rsp
ffffffff81367569: 49 89 f6 mov %rsi,%r14
ffffffff8136756c: 48 89 fb mov %rdi,%rbx
#define DRM_SWITCH_POWER_DYNAMIC_OFF 3

static __inline__ int drm_core_check_feature(struct drm_device *dev,
int feature)
{
return ((dev->driver->driver_features & feature) ? 1 : 0);
ffffffff8136756f: 48 8b 43 20 mov 0x20(%rbx),%rax
uint32_t __user *set_connectors_ptr;
struct drm_modeset_acquire_ctx ctx;
int ret;
int i;

if (!drm_core_check_feature(dev, DRIVER_MODESET))
ffffffff81367573: f6 80 81 01 00 00 20 testb $0x20,0x181(%rax)
ffffffff8136757a: 75 09 jne ffffffff81367585 <drm_mode_setcrtc+0x35>
ffffffff8136757c: 6a ea pushq $0xffffffffffffffea
ffffffff8136757e: 41 5c pop %r12
ffffffff81367580: e9 d5 04 00 00 jmpq ffffffff81367a5a <drm_mode_setcrtc+0x50a>
ffffffff81367585: 6a de pushq $0xffffffffffffffde
ffffffff81367587: 41 5c pop %r12

/*
* Universal plane src offsets are only 16.16, prevent havoc for
* drivers using universal plane code internally.
*/
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
ffffffff81367589: 41 81 7e 14 ff ff 00 cmpl $0xffff,0x14(%r14)
ffffffff81367590: 00
ffffffff81367591: 0f 87 c3 04 00 00 ja ffffffff81367a5a <drm_mode_setcrtc+0x50a>
ffffffff81367597: 41 81 7e 18 ff ff 00 cmpl $0xffff,0x18(%r14)
ffffffff8136759e: 00
ffffffff8136759f: 0f 87 b5 04 00 00 ja ffffffff81367a5a <drm_mode_setcrtc+0x50a>
return -ERANGE;

crtc = drm_crtc_find(dev, crtc_req->crtc_id);
ffffffff813675a5: 41 8b 76 0c mov 0xc(%r14),%esi
ffffffff813675a9: 48 89 df mov %rbx,%rdi
ffffffff813675ac: e8 15 fe ff ff callq ffffffff813673c6 <drm_crtc_find>
ffffffff813675b1: 49 89 c5 mov %rax,%r13
if (!crtc) {
ffffffff813675b4: 4d 85 ed test %r13,%r13
ffffffff813675b7: 0f 84 7d 04 00 00 je ffffffff81367a3a <drm_mode_setcrtc+0x4ea>
ffffffff813675bd: 48 89 5d b0 mov %rbx,-0x50(%rbp)
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
return -ENOENT;
}
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
ffffffff813675c1: 41 8b 4d 78 mov 0x78(%r13),%ecx
ffffffff813675c5: 4d 8b 45 20 mov 0x20(%r13),%r8
ffffffff813675c9: 6a 04 pushq $0x4
ffffffff813675cb: 5e pop %rsi
ffffffff813675cc: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff813675d3: 48 c7 c2 e8 55 9b 81 mov $0xffffffff819b55e8,%rdx
ffffffff813675da: 31 c0 xor %eax,%eax
ffffffff813675dc: e8 45 c6 ff ff callq ffffffff81363c26 <drm_printk>

mutex_lock(&crtc->dev->mode_config.mutex);
ffffffff813675e1: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff813675e5: 48 81 c7 b0 02 00 00 add $0x2b0,%rdi
ffffffff813675ec: e8 b2 3c 2e 00 callq ffffffff8164b2a3 <mutex_lock>
ffffffff813675f1: 48 8d 9d 38 ff ff ff lea -0xc8(%rbp),%rbx
drm_modeset_acquire_init(&ctx, 0);
ffffffff813675f8: 31 f6 xor %esi,%esi
ffffffff813675fa: 48 89 df mov %rbx,%rdi
ffffffff813675fd: e8 ef 7d 00 00 callq ffffffff8136f3f1 <drm_modeset_acquire_init>
ffffffff81367602: 49 8d 46 24 lea 0x24(%r14),%rax
ffffffff81367606: 48 89 45 a0 mov %rax,-0x60(%rbp)
ffffffff8136760a: 31 c0 xor %eax,%eax
ffffffff8136760c: 48 89 45 c0 mov %rax,-0x40(%rbp)
ffffffff81367610: 31 c0 xor %eax,%eax
ffffffff81367612: 48 89 45 d0 mov %rax,-0x30(%rbp)
ffffffff81367616: 31 c0 xor %eax,%eax
ffffffff81367618: 48 89 45 c8 mov %rax,-0x38(%rbp)
ffffffff8136761c: 45 31 ff xor %r15d,%r15d
ffffffff8136761f: 48 89 45 a8 mov %rax,-0x58(%rbp)
ffffffff81367623: 4c 89 6d b8 mov %r13,-0x48(%rbp)
ffffffff81367627: e9 0a 03 00 00 jmpq ffffffff81367936 <drm_mode_setcrtc+0x3e6>
ffffffff8136762c: 48 8d 9d 38 ff ff ff lea -0xc8(%rbp),%rbx
}
}
kfree(connector_set);
drm_mode_destroy(dev, mode);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
ffffffff81367633: 48 89 df mov %rbx,%rdi
ffffffff81367636: e8 88 7e 00 00 callq ffffffff8136f4c3 <drm_modeset_backoff>
ffffffff8136763b: e9 f6 02 00 00 jmpq ffffffff81367936 <drm_mode_setcrtc+0x3e6>
goto out;
if (crtc_req->mode_valid) {
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
if (!crtc->primary->fb) {
ffffffff81367640: 49 8b 85 98 00 00 00 mov 0x98(%r13),%rax
ffffffff81367647: 48 8b 98 b0 00 00 00 mov 0xb0(%rax),%rbx
ffffffff8136764e: 48 85 db test %rbx,%rbx
ffffffff81367651: 0f 84 19 01 00 00 je ffffffff81367770 <drm_mode_setcrtc+0x220>
*
* This function increments the framebuffer's reference count.
*/
static inline void drm_framebuffer_get(struct drm_framebuffer *fb)
{
drm_mode_object_get(&fb->base);
ffffffff81367657: 48 8d 7b 18 lea 0x18(%rbx),%rdi
ffffffff8136765b: e8 97 de 00 00 callq ffffffff813754f7 <drm_mode_object_get>
ffffffff81367660: 48 89 5d d0 mov %rbx,-0x30(%rbp)
ffffffff81367664: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff81367668: 48 8b 5d b0 mov -0x50(%rbp),%rbx
ret = -ENOENT;
goto out;
}
}

mode = drm_mode_create(dev);
ffffffff8136766c: 48 89 df mov %rbx,%rdi
ffffffff8136766f: e8 32 08 00 00 callq ffffffff81367ea6 <drm_mode_create>
if (!mode) {
ffffffff81367674: 48 85 c0 test %rax,%rax
ffffffff81367677: 74 38 je ffffffff813676b1 <drm_mode_setcrtc+0x161>
ffffffff81367679: 48 89 c1 mov %rax,%rcx
ret = -ENOMEM;
goto out;
}

ret = drm_mode_convert_umode(mode, &crtc_req->mode);
ffffffff8136767c: 48 89 4d c0 mov %rcx,-0x40(%rbp)
ffffffff81367680: 48 89 c7 mov %rax,%rdi
ffffffff81367683: 48 8b 75 a0 mov -0x60(%rbp),%rsi
ffffffff81367687: e8 3a 1b 00 00 callq ffffffff813691c6 <drm_mode_convert_umode>
ffffffff8136768c: 41 89 c4 mov %eax,%r12d
if (ret) {
ffffffff8136768f: 45 85 e4 test %r12d,%r12d
ffffffff81367692: 74 2c je ffffffff813676c0 <drm_mode_setcrtc+0x170>
DRM_DEBUG_KMS("Invalid mode\n");
ffffffff81367694: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff8136769b: 48 c7 c2 1c 7b 9b 81 mov $0xffffffff819b7b1c,%rdx
ffffffff813676a2: 31 c0 xor %eax,%eax
ffffffff813676a4: 6a 04 pushq $0x4
ffffffff813676a6: 5e pop %rsi
ffffffff813676a7: e8 7a c5 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff813676ac: e9 a0 02 00 00 jmpq ffffffff81367951 <drm_mode_setcrtc+0x401>
ffffffff813676b1: 31 c0 xor %eax,%eax
ffffffff813676b3: 48 89 45 c0 mov %rax,-0x40(%rbp)
ffffffff813676b7: 6a f4 pushq $0xfffffffffffffff4
ffffffff813676b9: 41 5c pop %r12
ffffffff813676bb: e9 91 02 00 00 jmpq ffffffff81367951 <drm_mode_setcrtc+0x401>
* Drivers not implementing the universal planes API use a
* default formats list provided by the DRM core which doesn't
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ffffffff813676c0: 49 8b bd 98 00 00 00 mov 0x98(%r13),%rdi
ffffffff813676c7: 80 bf a4 00 00 00 00 cmpb $0x0,0xa4(%rdi)
ffffffff813676ce: 0f 84 cf 00 00 00 je ffffffff813677a3 <drm_mode_setcrtc+0x253>
&format_name));
goto out;
}
}

ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
ffffffff813676d4: 41 8b 76 14 mov 0x14(%r14),%esi
ffffffff813676d8: 41 8b 56 18 mov 0x18(%r14),%edx
ffffffff813676dc: 4c 89 ef mov %r13,%rdi
ffffffff813676df: 48 8b 4d c0 mov -0x40(%rbp),%rcx
ffffffff813676e3: 4c 8b 45 d0 mov -0x30(%rbp),%r8
ffffffff813676e7: e8 de fd ff ff callq ffffffff813674ca <drm_crtc_check_viewport>
ffffffff813676ec: 41 89 c4 mov %eax,%r12d
mode, fb);
if (ret)
ffffffff813676ef: 45 85 e4 test %r12d,%r12d
ffffffff813676f2: 0f 85 59 02 00 00 jne ffffffff81367951 <drm_mode_setcrtc+0x401>
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff813676f8: 41 8b 4e 08 mov 0x8(%r14),%ecx
ffffffff813676fc: 48 8b 45 c0 mov -0x40(%rbp),%rax
ffffffff81367700: 48 85 c0 test %rax,%rax
ffffffff81367703: 74 1e je ffffffff81367723 <drm_mode_setcrtc+0x1d3>
ffffffff81367705: 85 c9 test %ecx,%ecx
ffffffff81367707: 75 1a jne ffffffff81367723 <drm_mode_setcrtc+0x1d3>
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ffffffff81367709: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff81367710: 48 c7 c2 43 7b 9b 81 mov $0xffffffff819b7b43,%rdx
ffffffff81367717: 31 c0 xor %eax,%eax
ffffffff81367719: 6a 04 pushq $0x4
ffffffff8136771b: 5e pop %rsi
ffffffff8136771c: e8 05 c5 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff81367721: eb 44 jmp ffffffff81367767 <drm_mode_setcrtc+0x217>
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff81367723: 48 85 c0 test %rax,%rax
ffffffff81367726: 0f 95 c0 setne %al
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
ffffffff81367729: 48 83 7d d0 00 cmpq $0x0,-0x30(%rbp)
ffffffff8136772e: 0f 95 c2 setne %dl
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff81367731: 85 c9 test %ecx,%ecx
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
ffffffff81367733: 74 1e je ffffffff81367753 <drm_mode_setcrtc+0x203>
ffffffff81367735: 20 d0 and %dl,%al
ffffffff81367737: 75 1a jne ffffffff81367753 <drm_mode_setcrtc+0x203>
DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
ffffffff81367739: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff81367740: 48 c7 c2 67 7b 9b 81 mov $0xffffffff819b7b67,%rdx
ffffffff81367747: 31 c0 xor %eax,%eax
ffffffff81367749: 6a 04 pushq $0x4
ffffffff8136774b: 5e pop %rsi
ffffffff8136774c: e8 d5 c4 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff81367751: eb 14 jmp ffffffff81367767 <drm_mode_setcrtc+0x217>
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff81367753: 85 c9 test %ecx,%ecx
crtc_req->count_connectors);
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0) {
ffffffff81367755: 74 3e je ffffffff81367795 <drm_mode_setcrtc+0x245>
u32 out_id;

/* Avoid unbounded kernel memory allocation */
if (crtc_req->count_connectors > config->num_connector) {
ffffffff81367757: 48 8b 45 b0 mov -0x50(%rbp),%rax
ffffffff8136775b: 3b 88 10 04 00 00 cmp 0x410(%rax),%ecx
ffffffff81367761: 0f 86 8d 00 00 00 jbe ffffffff813677f4 <drm_mode_setcrtc+0x2a4>
ffffffff81367767: 6a ea pushq $0xffffffffffffffea
ffffffff81367769: 41 5c pop %r12
ffffffff8136776b: e9 da 01 00 00 jmpq ffffffff8136794a <drm_mode_setcrtc+0x3fa>
if (crtc_req->mode_valid) {
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
if (!crtc->primary->fb) {
DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
ffffffff81367770: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff81367777: 48 c7 c2 ed 7a 9b 81 mov $0xffffffff819b7aed,%rdx
ffffffff8136777e: 31 c0 xor %eax,%eax
ffffffff81367780: 6a 04 pushq $0x4
ffffffff81367782: 5e pop %rsi
ffffffff81367783: e8 9e c4 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff81367788: 6a ea pushq $0xffffffffffffffea
ffffffff8136778a: 41 5c pop %r12
ffffffff8136778c: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff81367790: e9 b5 01 00 00 jmpq ffffffff8136794a <drm_mode_setcrtc+0x3fa>
ffffffff81367795: 31 d2 xor %edx,%edx
ffffffff81367797: 48 8d b5 38 ff ff ff lea -0xc8(%rbp),%rsi
ffffffff8136779e: e9 46 01 00 00 jmpq ffffffff813678e9 <drm_mode_setcrtc+0x399>
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ret = drm_plane_check_pixel_format(crtc->primary,
fb->format->format);
ffffffff813677a3: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff813677a7: 48 8b 40 38 mov 0x38(%rax),%rax
ffffffff813677ab: 8b 30 mov (%rax),%esi
* default formats list provided by the DRM core which doesn't
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ret = drm_plane_check_pixel_format(crtc->primary,
ffffffff813677ad: e8 40 f4 00 00 callq ffffffff81376bf2 <drm_plane_check_pixel_format>
ffffffff813677b2: 41 89 c4 mov %eax,%r12d
fb->format->format);
if (ret) {
ffffffff813677b5: 45 85 e4 test %r12d,%r12d
ffffffff813677b8: 0f 84 16 ff ff ff je ffffffff813676d4 <drm_mode_setcrtc+0x184>
struct drm_format_name_buf format_name;
DRM_DEBUG_KMS("Invalid pixel format %s\n",
ffffffff813677be: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff813677c2: 48 8b 40 38 mov 0x38(%rax),%rax
ffffffff813677c6: 8b 38 mov (%rax),%edi
ffffffff813677c8: 48 8d b5 18 ff ff ff lea -0xe8(%rbp),%rsi
ffffffff813677cf: e8 c7 03 00 00 callq ffffffff81367b9b <drm_get_format_name>
ffffffff813677d4: 48 89 c1 mov %rax,%rcx
ffffffff813677d7: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff813677de: 48 c7 c2 2a 7b 9b 81 mov $0xffffffff819b7b2a,%rdx
ffffffff813677e5: 31 c0 xor %eax,%eax
ffffffff813677e7: 6a 04 pushq $0x4
ffffffff813677e9: 5e pop %rsi
ffffffff813677ea: e8 37 c4 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff813677ef: e9 5d 01 00 00 jmpq ffffffff81367951 <drm_mode_setcrtc+0x401>
{
if (size != 0 && n > SIZE_MAX / size)
return NULL;
if (__builtin_constant_p(n) && __builtin_constant_p(size))
return kmalloc(n * size, flags);
return __kmalloc(n * size, flags);
ffffffff813677f4: 48 c1 e1 03 shl $0x3,%rcx
ffffffff813677f8: be c0 00 40 01 mov $0x14000c0,%esi
ffffffff813677fd: 48 89 cf mov %rcx,%rdi
ffffffff81367800: e8 85 78 dd ff callq ffffffff8113f08a <__kmalloc>
}

connector_set = kmalloc_array(crtc_req->count_connectors,
sizeof(struct drm_connector *),
GFP_KERNEL);
if (!connector_set) {
ffffffff81367805: 48 85 c0 test %rax,%rax
ffffffff81367808: 48 8d b5 38 ff ff ff lea -0xc8(%rbp),%rsi
ffffffff8136780f: 0f 84 c2 00 00 00 je ffffffff813678d7 <drm_mode_setcrtc+0x387>
ffffffff81367815: 31 db xor %ebx,%ebx
ffffffff81367817: 48 89 c2 mov %rax,%rdx
ffffffff8136781a: 48 89 55 c8 mov %rdx,-0x38(%rbp)
ffffffff8136781e: eb 35 jmp ffffffff81367855 <drm_mode_setcrtc+0x305>
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
ret = -ENOENT;
goto out;
}
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
ffffffff81367820: 41 8b 4d 28 mov 0x28(%r13),%ecx
ffffffff81367824: 4d 8b 45 48 mov 0x48(%r13),%r8
ffffffff81367828: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff8136782f: 48 c7 c2 94 57 9b 81 mov $0xffffffff819b5794,%rdx
ffffffff81367836: 31 c0 xor %eax,%eax
ffffffff81367838: 6a 04 pushq $0x4
ffffffff8136783a: 5e pop %rsi
ffffffff8136783b: e8 e6 c3 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff81367840: 48 8b 45 c8 mov -0x38(%rbp),%rax
connector->base.id,
connector->name);

connector_set[i] = connector;
ffffffff81367844: 4e 89 2c f8 mov %r13,(%rax,%r15,8)
if (!connector_set) {
ret = -ENOMEM;
goto out;
}

for (i = 0; i < crtc_req->count_connectors; i++) {
ffffffff81367848: ff c3 inc %ebx
ffffffff8136784a: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff8136784e: 48 8d b5 38 ff ff ff lea -0xc8(%rbp),%rsi
ffffffff81367855: 41 8b 56 08 mov 0x8(%r14),%edx
ffffffff81367859: 39 d3 cmp %edx,%ebx
ffffffff8136785b: 0f 83 85 00 00 00 jae ffffffff813678e6 <drm_mode_setcrtc+0x396>
connector_set[i] = NULL;
ffffffff81367861: 4c 63 fb movslq %ebx,%r15
ffffffff81367864: 4a 83 24 f8 00 andq $0x0,(%rax,%r15,8)
set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
if (get_user(out_id, &set_connectors_ptr[i])) {
ffffffff81367869: 4a 8d 04 bd 00 00 00 lea 0x0(,%r15,4),%rax
ffffffff81367870: 00
ffffffff81367871: 49 03 06 add (%r14),%rax
ffffffff81367874: 48 8b 65 a8 mov -0x58(%rbp),%rsp
ffffffff81367878: e8 73 26 f1 ff callq ffffffff81279ef0 <__get_user_4>
ffffffff8136787d: 49 89 d4 mov %rdx,%r12
ffffffff81367880: 48 89 65 a8 mov %rsp,-0x58(%rbp)
ffffffff81367884: 85 c0 test %eax,%eax
ffffffff81367886: 0f 85 a0 00 00 00 jne ffffffff8136792c <drm_mode_setcrtc+0x3dc>
*/
static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
uint32_t id)
{
struct drm_mode_object *mo;
mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
ffffffff8136788c: ba c0 c0 c0 c0 mov $0xc0c0c0c0,%edx
ffffffff81367891: 48 8b 7d b0 mov -0x50(%rbp),%rdi
ffffffff81367895: 44 89 e6 mov %r12d,%esi
ffffffff81367898: e8 f7 db 00 00 callq ffffffff81375494 <drm_mode_object_find>
ffffffff8136789d: 49 89 c5 mov %rax,%r13
return mo ? obj_to_connector(mo) : NULL;
ffffffff813678a0: 4d 85 ed test %r13,%r13
ret = -EFAULT;
goto out;
}

connector = drm_connector_lookup(dev, out_id);
if (!connector) {
ffffffff813678a3: 74 0a je ffffffff813678af <drm_mode_setcrtc+0x35f>
ffffffff813678a5: 49 83 c5 d8 add $0xffffffffffffffd8,%r13
ffffffff813678a9: 0f 85 71 ff ff ff jne ffffffff81367820 <drm_mode_setcrtc+0x2d0>
DRM_DEBUG_KMS("Connector id %d unknown\n",
ffffffff813678af: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff813678b6: 48 c7 c2 95 7b 9b 81 mov $0xffffffff819b7b95,%rdx
ffffffff813678bd: 31 c0 xor %eax,%eax
ffffffff813678bf: 6a 04 pushq $0x4
ffffffff813678c1: 5e pop %rsi
ffffffff813678c2: 44 89 e1 mov %r12d,%ecx
ffffffff813678c5: e8 5c c3 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff813678ca: 6a fe pushq $0xfffffffffffffffe
ffffffff813678cc: 41 5c pop %r12
ffffffff813678ce: 4c 8b 7d c8 mov -0x38(%rbp),%r15
ffffffff813678d2: e9 b5 fe ff ff jmpq ffffffff8136778c <drm_mode_setcrtc+0x23c>
if (crtc_req->count_connectors > config->num_connector) {
ret = -EINVAL;
goto out;
}

connector_set = kmalloc_array(crtc_req->count_connectors,
ffffffff813678d7: 49 89 c7 mov %rax,%r15
ffffffff813678da: 6a f4 pushq $0xfffffffffffffff4
ffffffff813678dc: 41 5c pop %r12
ffffffff813678de: 31 c0 xor %eax,%eax
ffffffff813678e0: 48 89 45 c8 mov %rax,-0x38(%rbp)
ffffffff813678e4: eb 64 jmp ffffffff8136794a <drm_mode_setcrtc+0x3fa>
ffffffff813678e6: 49 89 c7 mov %rax,%r15

connector_set[i] = connector;
}
}

set.crtc = crtc;
ffffffff813678e9: 4c 89 ad 78 ff ff ff mov %r13,-0x88(%rbp)
set.x = crtc_req->x;
ffffffff813678f0: 41 8b 4e 14 mov 0x14(%r14),%ecx
ffffffff813678f4: 89 4d 88 mov %ecx,-0x78(%rbp)
set.y = crtc_req->y;
ffffffff813678f7: 41 8b 4e 18 mov 0x18(%r14),%ecx
ffffffff813678fb: 89 4d 8c mov %ecx,-0x74(%rbp)
set.mode = mode;
ffffffff813678fe: 48 8b 45 c0 mov -0x40(%rbp),%rax
ffffffff81367902: 48 89 45 80 mov %rax,-0x80(%rbp)
set.connectors = connector_set;
ffffffff81367906: 4c 89 7d 90 mov %r15,-0x70(%rbp)
set.num_connectors = crtc_req->count_connectors;
ffffffff8136790a: 89 d0 mov %edx,%eax
ffffffff8136790c: 48 89 45 98 mov %rax,-0x68(%rbp)
set.fb = fb;
ffffffff81367910: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff81367914: 48 89 85 70 ff ff ff mov %rax,-0x90(%rbp)
ret = __drm_mode_set_config_internal(&set, &ctx);
ffffffff8136791b: 48 8d bd 70 ff ff ff lea -0x90(%rbp),%rdi
ffffffff81367922: e8 bf fa ff ff callq ffffffff813673e6 <__drm_mode_set_config_internal>
ffffffff81367927: 41 89 c4 mov %eax,%r12d
ffffffff8136792a: eb 1e jmp ffffffff8136794a <drm_mode_setcrtc+0x3fa>
ffffffff8136792c: 6a f2 pushq $0xfffffffffffffff2
ffffffff8136792e: 41 5c pop %r12
ffffffff81367930: 4c 8b 7d c8 mov -0x38(%rbp),%r15
ffffffff81367934: eb 14 jmp ffffffff8136794a <drm_mode_setcrtc+0x3fa>
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);

mutex_lock(&crtc->dev->mode_config.mutex);
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
ffffffff81367936: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff8136793a: 48 89 de mov %rbx,%rsi
ffffffff8136793d: e8 08 7b 00 00 callq ffffffff8136f44a <drm_modeset_lock_all_ctx>
ffffffff81367942: 41 89 c4 mov %eax,%r12d
if (ret)
ffffffff81367945: 45 85 e4 test %r12d,%r12d
ffffffff81367948: 74 16 je ffffffff81367960 <drm_mode_setcrtc+0x410>
set.num_connectors = crtc_req->count_connectors;
set.fb = fb;
ret = __drm_mode_set_config_internal(&set, &ctx);

out:
if (fb)
ffffffff8136794a: 48 83 7d d0 00 cmpq $0x0,-0x30(%rbp)
ffffffff8136794f: 74 6b je ffffffff813679bc <drm_mode_setcrtc+0x46c>
* This function decrements the framebuffer's reference count and frees the
* framebuffer if the reference count drops to zero.
*/
static inline void drm_framebuffer_put(struct drm_framebuffer *fb)
{
drm_mode_object_put(&fb->base);
ffffffff81367951: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff81367955: 48 8d 78 18 lea 0x18(%rax),%rdi
ffffffff81367959: e8 46 db 00 00 callq ffffffff813754a4 <drm_mode_object_put>
ffffffff8136795e: eb 62 jmp ffffffff813679c2 <drm_mode_setcrtc+0x472>
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
if (ret)
goto out;
if (crtc_req->mode_valid) {
ffffffff81367960: 41 83 7e 20 00 cmpl $0x0,0x20(%r14)
ffffffff81367965: 0f 84 8d fd ff ff je ffffffff813676f8 <drm_mode_setcrtc+0x1a8>
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
ffffffff8136796b: 41 8b 76 10 mov 0x10(%r14),%esi
ffffffff8136796f: 83 fe ff cmp $0xffffffff,%esi
ffffffff81367972: 0f 84 c8 fc ff ff je ffffffff81367640 <drm_mode_setcrtc+0xf0>
ffffffff81367978: 48 8b 5d b0 mov -0x50(%rbp),%rbx
}
fb = crtc->primary->fb;
/* Make refcounting symmetric with the lookup path. */
drm_framebuffer_get(fb);
} else {
fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
ffffffff8136797c: 48 89 df mov %rbx,%rdi
ffffffff8136797f: e8 a3 b3 00 00 callq ffffffff81372d27 <drm_framebuffer_lookup>
ffffffff81367984: 48 89 c1 mov %rax,%rcx
if (!fb) {
ffffffff81367987: 48 89 4d d0 mov %rcx,-0x30(%rbp)
ffffffff8136798b: 48 85 c0 test %rax,%rax
ffffffff8136798e: 0f 85 d8 fc ff ff jne ffffffff8136766c <drm_mode_setcrtc+0x11c>
DRM_DEBUG_KMS("Unknown FB ID%d\n",
ffffffff81367994: 41 8b 4e 10 mov 0x10(%r14),%ecx
ffffffff81367998: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff8136799f: 48 c7 c2 0b 7b 9b 81 mov $0xffffffff819b7b0b,%rdx
ffffffff813679a6: 31 c0 xor %eax,%eax
ffffffff813679a8: 6a 04 pushq $0x4
ffffffff813679aa: 5e pop %rsi
ffffffff813679ab: e8 76 c2 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff813679b0: 31 c0 xor %eax,%eax
ffffffff813679b2: 48 89 45 d0 mov %rax,-0x30(%rbp)
ffffffff813679b6: 6a fe pushq $0xfffffffffffffffe
ffffffff813679b8: 41 5c pop %r12
ffffffff813679ba: eb 06 jmp ffffffff813679c2 <drm_mode_setcrtc+0x472>
ffffffff813679bc: 31 c0 xor %eax,%eax
ffffffff813679be: 48 89 45 d0 mov %rax,-0x30(%rbp)

out:
if (fb)
drm_framebuffer_put(fb);

if (connector_set) {
ffffffff813679c2: 4d 85 ff test %r15,%r15
ffffffff813679c5: 74 27 je ffffffff813679ee <drm_mode_setcrtc+0x49e>
ffffffff813679c7: 31 db xor %ebx,%ebx
ffffffff813679c9: eb 17 jmp ffffffff813679e2 <drm_mode_setcrtc+0x492>
for (i = 0; i < crtc_req->count_connectors; i++) {
if (connector_set[i])
ffffffff813679cb: 48 63 c3 movslq %ebx,%rax
ffffffff813679ce: 49 8b 3c c7 mov (%r15,%rax,8),%rdi
ffffffff813679d2: 48 85 ff test %rdi,%rdi
ffffffff813679d5: 74 09 je ffffffff813679e0 <drm_mode_setcrtc+0x490>
* This function decrements the connector's reference count and frees the
* object if the reference count drops to zero.
*/
static inline void drm_connector_put(struct drm_connector *connector)
{
drm_mode_object_put(&connector->base);
ffffffff813679d7: 48 83 c7 28 add $0x28,%rdi
ffffffff813679db: e8 c4 da 00 00 callq ffffffff813754a4 <drm_mode_object_put>
out:
if (fb)
drm_framebuffer_put(fb);

if (connector_set) {
for (i = 0; i < crtc_req->count_connectors; i++) {
ffffffff813679e0: ff c3 inc %ebx
ffffffff813679e2: 41 3b 5e 08 cmp 0x8(%r14),%ebx
ffffffff813679e6: 72 e3 jb ffffffff813679cb <drm_mode_setcrtc+0x47b>
ffffffff813679e8: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff813679ec: eb 03 jmp ffffffff813679f1 <drm_mode_setcrtc+0x4a1>
ffffffff813679ee: 45 31 ff xor %r15d,%r15d
if (connector_set[i])
drm_connector_put(connector_set[i]);
}
}
kfree(connector_set);
ffffffff813679f1: 48 8b 7d c8 mov -0x38(%rbp),%rdi
ffffffff813679f5: e8 55 78 dd ff callq ffffffff8113f24f <kfree>
drm_mode_destroy(dev, mode);
ffffffff813679fa: 48 8b 7d b0 mov -0x50(%rbp),%rdi
ffffffff813679fe: 48 8b 75 c0 mov -0x40(%rbp),%rsi
ffffffff81367a02: e8 ef 04 00 00 callq ffffffff81367ef6 <drm_mode_destroy>
if (ret == -EDEADLK) {
ffffffff81367a07: 41 83 fc dd cmp $0xffffffdd,%r12d
ffffffff81367a0b: 0f 84 1b fc ff ff je ffffffff8136762c <drm_mode_setcrtc+0xdc>
ffffffff81367a11: 4c 8d b5 38 ff ff ff lea -0xc8(%rbp),%r14
drm_modeset_backoff(&ctx);
goto retry;
}
drm_modeset_drop_locks(&ctx);
ffffffff81367a18: 4c 89 f7 mov %r14,%rdi
ffffffff81367a1b: e8 62 7b 00 00 callq ffffffff8136f582 <drm_modeset_drop_locks>
drm_modeset_acquire_fini(&ctx);
ffffffff81367a20: 4c 89 f7 mov %r14,%rdi
ffffffff81367a23: e8 ad 7a 00 00 callq ffffffff8136f4d5 <drm_modeset_acquire_fini>
mutex_unlock(&crtc->dev->mode_config.mutex);
ffffffff81367a28: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff81367a2c: 48 81 c7 b0 02 00 00 add $0x2b0,%rdi
ffffffff81367a33: e8 b0 38 2e 00 callq ffffffff8164b2e8 <mutex_unlock>
ffffffff81367a38: eb 20 jmp ffffffff81367a5a <drm_mode_setcrtc+0x50a>
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;

crtc = drm_crtc_find(dev, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
ffffffff81367a3a: 41 8b 4e 0c mov 0xc(%r14),%ecx
ffffffff81367a3e: 6a 04 pushq $0x4
ffffffff81367a40: 5e pop %rsi
ffffffff81367a41: 48 c7 c7 5d 82 95 81 mov $0xffffffff8195825d,%rdi
ffffffff81367a48: 48 c7 c2 d9 7a 9b 81 mov $0xffffffff819b7ad9,%rdx
ffffffff81367a4f: 31 c0 xor %eax,%eax
ffffffff81367a51: e8 d0 c1 ff ff callq ffffffff81363c26 <drm_printk>
ffffffff81367a56: 6a fe pushq $0xfffffffffffffffe
ffffffff81367a58: 41 5c pop %r12
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
mutex_unlock(&crtc->dev->mode_config.mutex);

return ret;
}
ffffffff81367a5a: 44 89 e0 mov %r12d,%eax
ffffffff81367a5d: 48 81 c4 c0 00 00 00 add $0xc0,%rsp
ffffffff81367a64: 5b pop %rbx
ffffffff81367a65: 41 5c pop %r12
ffffffff81367a67: 41 5d pop %r13
ffffffff81367a69: 41 5e pop %r14
ffffffff81367a6b: 41 5f pop %r15
ffffffff81367a6d: 5d pop %rbp
ffffffff81367a6e: c3 retq

============================================================

Without f05058c4d652:

ffffffff8136744c <drm_mode_setcrtc>:
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_setcrtc(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
ffffffff8136744c: e8 1f 71 2e 00 callq ffffffff8164e570 <__fentry__>
ffffffff81367451: 55 push %rbp
ffffffff81367452: 48 89 e5 mov %rsp,%rbp
ffffffff81367455: 41 57 push %r15
ffffffff81367457: 41 56 push %r14
ffffffff81367459: 41 55 push %r13
ffffffff8136745b: 41 54 push %r12
ffffffff8136745d: 53 push %rbx
ffffffff8136745e: 48 81 ec b8 00 00 00 sub $0xb8,%rsp
ffffffff81367465: 49 89 f6 mov %rsi,%r14
ffffffff81367468: 48 89 fb mov %rdi,%rbx
#define DRM_SWITCH_POWER_DYNAMIC_OFF 3

static __inline__ int drm_core_check_feature(struct drm_device *dev,
int feature)
{
return ((dev->driver->driver_features & feature) ? 1 : 0);
ffffffff8136746b: 48 8b 43 20 mov 0x20(%rbx),%rax
uint32_t __user *set_connectors_ptr;
struct drm_modeset_acquire_ctx ctx;
int ret;
int i;

if (!drm_core_check_feature(dev, DRIVER_MODESET))
ffffffff8136746f: f6 80 81 01 00 00 20 testb $0x20,0x181(%rax)
ffffffff81367476: 75 09 jne ffffffff81367481 <drm_mode_setcrtc+0x35>
ffffffff81367478: 6a ea pushq $0xffffffffffffffea
ffffffff8136747a: 41 5c pop %r12
ffffffff8136747c: e9 be 04 00 00 jmpq ffffffff8136793f <drm_mode_setcrtc+0x4f3>
ffffffff81367481: 6a de pushq $0xffffffffffffffde
ffffffff81367483: 41 5c pop %r12

/*
* Universal plane src offsets are only 16.16, prevent havoc for
* drivers using universal plane code internally.
*/
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
ffffffff81367485: 41 81 7e 14 ff ff 00 cmpl $0xffff,0x14(%r14)
ffffffff8136748c: 00
ffffffff8136748d: 0f 87 ac 04 00 00 ja ffffffff8136793f <drm_mode_setcrtc+0x4f3>
ffffffff81367493: 41 81 7e 18 ff ff 00 cmpl $0xffff,0x18(%r14)
ffffffff8136749a: 00
ffffffff8136749b: 0f 87 9e 04 00 00 ja ffffffff8136793f <drm_mode_setcrtc+0x4f3>
return -ERANGE;

crtc = drm_crtc_find(dev, crtc_req->crtc_id);
ffffffff813674a1: 41 8b 76 0c mov 0xc(%r14),%esi
ffffffff813674a5: 48 89 df mov %rbx,%rdi
ffffffff813674a8: e8 15 fe ff ff callq ffffffff813672c2 <drm_crtc_find>
ffffffff813674ad: 49 89 c5 mov %rax,%r13
if (!crtc) {
ffffffff813674b0: 4d 85 ed test %r13,%r13
ffffffff813674b3: 0f 84 66 04 00 00 je ffffffff8136791f <drm_mode_setcrtc+0x4d3>
ffffffff813674b9: 48 89 5d b0 mov %rbx,-0x50(%rbp)
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
return -ENOENT;
}
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
ffffffff813674bd: 41 8b 4d 78 mov 0x78(%r13),%ecx
ffffffff813674c1: 4d 8b 45 20 mov 0x20(%r13),%r8
ffffffff813674c5: 6a 04 pushq $0x4
ffffffff813674c7: 5e pop %rsi
ffffffff813674c8: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff813674cf: 48 c7 c2 d8 55 9b 81 mov $0xffffffff819b55d8,%rdx
ffffffff813674d6: 31 c0 xor %eax,%eax
ffffffff813674d8: e8 45 c6 ff ff callq ffffffff81363b22 <drm_printk>

mutex_lock(&crtc->dev->mode_config.mutex);
ffffffff813674dd: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff813674e1: 48 81 c7 b0 02 00 00 add $0x2b0,%rdi
ffffffff813674e8: e8 e6 3b 2e 00 callq ffffffff8164b0d3 <mutex_lock>
ffffffff813674ed: 48 8d 9d 40 ff ff ff lea -0xc0(%rbp),%rbx
drm_modeset_acquire_init(&ctx, 0);
ffffffff813674f4: 31 f6 xor %esi,%esi
ffffffff813674f6: 48 89 df mov %rbx,%rdi
ffffffff813674f9: e8 d8 7d 00 00 callq ffffffff8136f2d6 <drm_modeset_acquire_init>
ffffffff813674fe: 49 8d 46 24 lea 0x24(%r14),%rax
ffffffff81367502: 48 89 45 a8 mov %rax,-0x58(%rbp)
ffffffff81367506: 31 c0 xor %eax,%eax
ffffffff81367508: 48 89 45 c0 mov %rax,-0x40(%rbp)
ffffffff8136750c: 31 c0 xor %eax,%eax
ffffffff8136750e: 48 89 45 d0 mov %rax,-0x30(%rbp)
ffffffff81367512: 31 c0 xor %eax,%eax
ffffffff81367514: 48 89 45 c8 mov %rax,-0x38(%rbp)
ffffffff81367518: 45 31 ff xor %r15d,%r15d
ffffffff8136751b: 4c 89 6d b8 mov %r13,-0x48(%rbp)
ffffffff8136751f: e9 f7 02 00 00 jmpq ffffffff8136781b <drm_mode_setcrtc+0x3cf>
ffffffff81367524: 48 8d 9d 40 ff ff ff lea -0xc0(%rbp),%rbx
}
}
kfree(connector_set);
drm_mode_destroy(dev, mode);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
ffffffff8136752b: 48 89 df mov %rbx,%rdi
ffffffff8136752e: e8 75 7e 00 00 callq ffffffff8136f3a8 <drm_modeset_backoff>
ffffffff81367533: e9 e3 02 00 00 jmpq ffffffff8136781b <drm_mode_setcrtc+0x3cf>
goto out;
if (crtc_req->mode_valid) {
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
if (!crtc->primary->fb) {
ffffffff81367538: 49 8b 85 98 00 00 00 mov 0x98(%r13),%rax
ffffffff8136753f: 48 8b 98 b0 00 00 00 mov 0xb0(%rax),%rbx
ffffffff81367546: 48 85 db test %rbx,%rbx
ffffffff81367549: 0f 84 19 01 00 00 je ffffffff81367668 <drm_mode_setcrtc+0x21c>
*
* This function increments the framebuffer's reference count.
*/
static inline void drm_framebuffer_get(struct drm_framebuffer *fb)
{
drm_mode_object_get(&fb->base);
ffffffff8136754f: 48 8d 7b 18 lea 0x18(%rbx),%rdi
ffffffff81367553: e8 45 de 00 00 callq ffffffff8137539d <drm_mode_object_get>
ffffffff81367558: 48 89 5d d0 mov %rbx,-0x30(%rbp)
ffffffff8136755c: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff81367560: 48 8b 5d b0 mov -0x50(%rbp),%rbx
ret = -ENOENT;
goto out;
}
}

mode = drm_mode_create(dev);
ffffffff81367564: 48 89 df mov %rbx,%rdi
ffffffff81367567: e8 1f 08 00 00 callq ffffffff81367d8b <drm_mode_create>
if (!mode) {
ffffffff8136756c: 48 85 c0 test %rax,%rax
ffffffff8136756f: 74 38 je ffffffff813675a9 <drm_mode_setcrtc+0x15d>
ffffffff81367571: 48 89 c1 mov %rax,%rcx
ret = -ENOMEM;
goto out;
}

ret = drm_mode_convert_umode(mode, &crtc_req->mode);
ffffffff81367574: 48 89 4d c0 mov %rcx,-0x40(%rbp)
ffffffff81367578: 48 89 c7 mov %rax,%rdi
ffffffff8136757b: 48 8b 75 a8 mov -0x58(%rbp),%rsi
ffffffff8136757f: e8 27 1b 00 00 callq ffffffff813690ab <drm_mode_convert_umode>
ffffffff81367584: 41 89 c4 mov %eax,%r12d
if (ret) {
ffffffff81367587: 45 85 e4 test %r12d,%r12d
ffffffff8136758a: 74 2c je ffffffff813675b8 <drm_mode_setcrtc+0x16c>
DRM_DEBUG_KMS("Invalid mode\n");
ffffffff8136758c: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff81367593: 48 c7 c2 0c 7b 9b 81 mov $0xffffffff819b7b0c,%rdx
ffffffff8136759a: 31 c0 xor %eax,%eax
ffffffff8136759c: 6a 04 pushq $0x4
ffffffff8136759e: 5e pop %rsi
ffffffff8136759f: e8 7e c5 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff813675a4: e9 8d 02 00 00 jmpq ffffffff81367836 <drm_mode_setcrtc+0x3ea>
ffffffff813675a9: 31 c0 xor %eax,%eax
ffffffff813675ab: 48 89 45 c0 mov %rax,-0x40(%rbp)
ffffffff813675af: 6a f4 pushq $0xfffffffffffffff4
ffffffff813675b1: 41 5c pop %r12
ffffffff813675b3: e9 7e 02 00 00 jmpq ffffffff81367836 <drm_mode_setcrtc+0x3ea>
* Drivers not implementing the universal planes API use a
* default formats list provided by the DRM core which doesn't
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ffffffff813675b8: 49 8b bd 98 00 00 00 mov 0x98(%r13),%rdi
ffffffff813675bf: 80 bf a4 00 00 00 00 cmpb $0x0,0xa4(%rdi)
ffffffff813675c6: 0f 84 cf 00 00 00 je ffffffff8136769b <drm_mode_setcrtc+0x24f>
&format_name));
goto out;
}
}

ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
ffffffff813675cc: 41 8b 76 14 mov 0x14(%r14),%esi
ffffffff813675d0: 41 8b 56 18 mov 0x18(%r14),%edx
ffffffff813675d4: 4c 89 ef mov %r13,%rdi
ffffffff813675d7: 48 8b 4d c0 mov -0x40(%rbp),%rcx
ffffffff813675db: 4c 8b 45 d0 mov -0x30(%rbp),%r8
ffffffff813675df: e8 e2 fd ff ff callq ffffffff813673c6 <drm_crtc_check_viewport>
ffffffff813675e4: 41 89 c4 mov %eax,%r12d
mode, fb);
if (ret)
ffffffff813675e7: 45 85 e4 test %r12d,%r12d
ffffffff813675ea: 0f 85 46 02 00 00 jne ffffffff81367836 <drm_mode_setcrtc+0x3ea>
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff813675f0: 41 8b 4e 08 mov 0x8(%r14),%ecx
ffffffff813675f4: 48 8b 45 c0 mov -0x40(%rbp),%rax
ffffffff813675f8: 48 85 c0 test %rax,%rax
ffffffff813675fb: 74 1e je ffffffff8136761b <drm_mode_setcrtc+0x1cf>
ffffffff813675fd: 85 c9 test %ecx,%ecx
ffffffff813675ff: 75 1a jne ffffffff8136761b <drm_mode_setcrtc+0x1cf>
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ffffffff81367601: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff81367608: 48 c7 c2 33 7b 9b 81 mov $0xffffffff819b7b33,%rdx
ffffffff8136760f: 31 c0 xor %eax,%eax
ffffffff81367611: 6a 04 pushq $0x4
ffffffff81367613: 5e pop %rsi
ffffffff81367614: e8 09 c5 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff81367619: eb 44 jmp ffffffff8136765f <drm_mode_setcrtc+0x213>
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff8136761b: 48 85 c0 test %rax,%rax
ffffffff8136761e: 0f 95 c0 setne %al
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
ffffffff81367621: 48 83 7d d0 00 cmpq $0x0,-0x30(%rbp)
ffffffff81367626: 0f 95 c2 setne %dl
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff81367629: 85 c9 test %ecx,%ecx
DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
ffffffff8136762b: 74 1e je ffffffff8136764b <drm_mode_setcrtc+0x1ff>
ffffffff8136762d: 20 d0 and %dl,%al
ffffffff8136762f: 75 1a jne ffffffff8136764b <drm_mode_setcrtc+0x1ff>
DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
ffffffff81367631: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff81367638: 48 c7 c2 57 7b 9b 81 mov $0xffffffff819b7b57,%rdx
ffffffff8136763f: 31 c0 xor %eax,%eax
ffffffff81367641: 6a 04 pushq $0x4
ffffffff81367643: 5e pop %rsi
ffffffff81367644: e8 d9 c4 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff81367649: eb 14 jmp ffffffff8136765f <drm_mode_setcrtc+0x213>
if (ret)
goto out;

}

if (crtc_req->count_connectors == 0 && mode) {
ffffffff8136764b: 85 c9 test %ecx,%ecx
crtc_req->count_connectors);
ret = -EINVAL;
goto out;
}

if (crtc_req->count_connectors > 0) {
ffffffff8136764d: 74 3e je ffffffff8136768d <drm_mode_setcrtc+0x241>
u32 out_id;

/* Avoid unbounded kernel memory allocation */
if (crtc_req->count_connectors > config->num_connector) {
ffffffff8136764f: 48 8b 45 b0 mov -0x50(%rbp),%rax
ffffffff81367653: 3b 88 10 04 00 00 cmp 0x410(%rax),%ecx
ffffffff81367659: 0f 86 8d 00 00 00 jbe ffffffff813676ec <drm_mode_setcrtc+0x2a0>
ffffffff8136765f: 6a ea pushq $0xffffffffffffffea
ffffffff81367661: 41 5c pop %r12
ffffffff81367663: e9 c7 01 00 00 jmpq ffffffff8136782f <drm_mode_setcrtc+0x3e3>
if (crtc_req->mode_valid) {
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
if (!crtc->primary->fb) {
DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
ffffffff81367668: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff8136766f: 48 c7 c2 dd 7a 9b 81 mov $0xffffffff819b7add,%rdx
ffffffff81367676: 31 c0 xor %eax,%eax
ffffffff81367678: 6a 04 pushq $0x4
ffffffff8136767a: 5e pop %rsi
ffffffff8136767b: e8 a2 c4 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff81367680: 6a ea pushq $0xffffffffffffffea
ffffffff81367682: 41 5c pop %r12
ffffffff81367684: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff81367688: e9 a2 01 00 00 jmpq ffffffff8136782f <drm_mode_setcrtc+0x3e3>
ffffffff8136768d: 31 d2 xor %edx,%edx
ffffffff8136768f: 48 8d b5 40 ff ff ff lea -0xc0(%rbp),%rsi
ffffffff81367696: e9 36 01 00 00 jmpq ffffffff813677d1 <drm_mode_setcrtc+0x385>
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ret = drm_plane_check_pixel_format(crtc->primary,
fb->format->format);
ffffffff8136769b: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff8136769f: 48 8b 40 38 mov 0x38(%rax),%rax
ffffffff813676a3: 8b 30 mov (%rax),%esi
* default formats list provided by the DRM core which doesn't
* match real hardware capabilities. Skip the check in that
* case.
*/
if (!crtc->primary->format_default) {
ret = drm_plane_check_pixel_format(crtc->primary,
ffffffff813676a5: e8 ee f3 00 00 callq ffffffff81376a98 <drm_plane_check_pixel_format>
ffffffff813676aa: 41 89 c4 mov %eax,%r12d
fb->format->format);
if (ret) {
ffffffff813676ad: 45 85 e4 test %r12d,%r12d
ffffffff813676b0: 0f 84 16 ff ff ff je ffffffff813675cc <drm_mode_setcrtc+0x180>
struct drm_format_name_buf format_name;
DRM_DEBUG_KMS("Invalid pixel format %s\n",
ffffffff813676b6: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff813676ba: 48 8b 40 38 mov 0x38(%rax),%rax
ffffffff813676be: 8b 38 mov (%rax),%edi
ffffffff813676c0: 48 8d b5 20 ff ff ff lea -0xe0(%rbp),%rsi
ffffffff813676c7: e8 b4 03 00 00 callq ffffffff81367a80 <drm_get_format_name>
ffffffff813676cc: 48 89 c1 mov %rax,%rcx
ffffffff813676cf: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff813676d6: 48 c7 c2 1a 7b 9b 81 mov $0xffffffff819b7b1a,%rdx
ffffffff813676dd: 31 c0 xor %eax,%eax
ffffffff813676df: 6a 04 pushq $0x4
ffffffff813676e1: 5e pop %rsi
ffffffff813676e2: e8 3b c4 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff813676e7: e9 4a 01 00 00 jmpq ffffffff81367836 <drm_mode_setcrtc+0x3ea>
{
if (size != 0 && n > SIZE_MAX / size)
return NULL;
if (__builtin_constant_p(n) && __builtin_constant_p(size))
return kmalloc(n * size, flags);
return __kmalloc(n * size, flags);
ffffffff813676ec: 48 c1 e1 03 shl $0x3,%rcx
ffffffff813676f0: be c0 00 40 01 mov $0x14000c0,%esi
ffffffff813676f5: 48 89 cf mov %rcx,%rdi
ffffffff813676f8: e8 cc 78 dd ff callq ffffffff8113efc9 <__kmalloc>
}

connector_set = kmalloc_array(crtc_req->count_connectors,
sizeof(struct drm_connector *),
GFP_KERNEL);
if (!connector_set) {
ffffffff813676fd: 48 85 c0 test %rax,%rax
ffffffff81367700: 48 8d b5 40 ff ff ff lea -0xc0(%rbp),%rsi
ffffffff81367707: 0f 84 b2 00 00 00 je ffffffff813677bf <drm_mode_setcrtc+0x373>
ffffffff8136770d: 31 db xor %ebx,%ebx
ffffffff8136770f: 48 89 c2 mov %rax,%rdx
ffffffff81367712: 48 89 55 c8 mov %rdx,-0x38(%rbp)
ffffffff81367716: eb 35 jmp ffffffff8136774d <drm_mode_setcrtc+0x301>
DRM_DEBUG_KMS("Connector id %d unknown\n",
out_id);
ret = -ENOENT;
goto out;
}
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
ffffffff81367718: 41 8b 4d 28 mov 0x28(%r13),%ecx
ffffffff8136771c: 4d 8b 45 48 mov 0x48(%r13),%r8
ffffffff81367720: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff81367727: 48 c7 c2 84 57 9b 81 mov $0xffffffff819b5784,%rdx
ffffffff8136772e: 31 c0 xor %eax,%eax
ffffffff81367730: 6a 04 pushq $0x4
ffffffff81367732: 5e pop %rsi
ffffffff81367733: e8 ea c3 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff81367738: 48 8b 45 c8 mov -0x38(%rbp),%rax
connector->base.id,
connector->name);

connector_set[i] = connector;
ffffffff8136773c: 4e 89 2c f8 mov %r13,(%rax,%r15,8)
if (!connector_set) {
ret = -ENOMEM;
goto out;
}

for (i = 0; i < crtc_req->count_connectors; i++) {
ffffffff81367740: ff c3 inc %ebx
ffffffff81367742: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff81367746: 48 8d b5 40 ff ff ff lea -0xc0(%rbp),%rsi
ffffffff8136774d: 41 8b 56 08 mov 0x8(%r14),%edx
ffffffff81367751: 39 d3 cmp %edx,%ebx
ffffffff81367753: 73 79 jae ffffffff813677ce <drm_mode_setcrtc+0x382>
connector_set[i] = NULL;
ffffffff81367755: 4c 63 fb movslq %ebx,%r15
ffffffff81367758: 4a 83 24 f8 00 andq $0x0,(%rax,%r15,8)
set_connectors_ptr = (uint32_t __user *)(unsigned long)crtc_req->set_connectors_ptr;
if (get_user(out_id, &set_connectors_ptr[i])) {
ffffffff8136775d: 4a 8d 04 bd 00 00 00 lea 0x0(,%r15,4),%rax
ffffffff81367764: 00
ffffffff81367765: 49 03 06 add (%r14),%rax
ffffffff81367768: e8 83 26 f1 ff callq ffffffff81279df0 <__get_user_4>
ffffffff8136776d: 49 89 d4 mov %rdx,%r12
ffffffff81367770: 85 c0 test %eax,%eax
ffffffff81367772: 0f 85 99 00 00 00 jne ffffffff81367811 <drm_mode_setcrtc+0x3c5>
*/
static inline struct drm_connector *drm_connector_lookup(struct drm_device *dev,
uint32_t id)
{
struct drm_mode_object *mo;
mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_CONNECTOR);
ffffffff81367778: ba c0 c0 c0 c0 mov $0xc0c0c0c0,%edx
ffffffff8136777d: 48 8b 7d b0 mov -0x50(%rbp),%rdi
ffffffff81367781: 44 89 e6 mov %r12d,%esi
ffffffff81367784: e8 b1 db 00 00 callq ffffffff8137533a <drm_mode_object_find>
ffffffff81367789: 49 89 c5 mov %rax,%r13
return mo ? obj_to_connector(mo) : NULL;
ffffffff8136778c: 4d 85 ed test %r13,%r13
ret = -EFAULT;
goto out;
}

connector = drm_connector_lookup(dev, out_id);
if (!connector) {
ffffffff8136778f: 74 06 je ffffffff81367797 <drm_mode_setcrtc+0x34b>
ffffffff81367791: 49 83 c5 d8 add $0xffffffffffffffd8,%r13
ffffffff81367795: 75 81 jne ffffffff81367718 <drm_mode_setcrtc+0x2cc>
DRM_DEBUG_KMS("Connector id %d unknown\n",
ffffffff81367797: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff8136779e: 48 c7 c2 85 7b 9b 81 mov $0xffffffff819b7b85,%rdx
ffffffff813677a5: 31 c0 xor %eax,%eax
ffffffff813677a7: 6a 04 pushq $0x4
ffffffff813677a9: 5e pop %rsi
ffffffff813677aa: 44 89 e1 mov %r12d,%ecx
ffffffff813677ad: e8 70 c3 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff813677b2: 6a fe pushq $0xfffffffffffffffe
ffffffff813677b4: 41 5c pop %r12
ffffffff813677b6: 4c 8b 7d c8 mov -0x38(%rbp),%r15
ffffffff813677ba: e9 c5 fe ff ff jmpq ffffffff81367684 <drm_mode_setcrtc+0x238>
if (crtc_req->count_connectors > config->num_connector) {
ret = -EINVAL;
goto out;
}

connector_set = kmalloc_array(crtc_req->count_connectors,
ffffffff813677bf: 49 89 c7 mov %rax,%r15
ffffffff813677c2: 6a f4 pushq $0xfffffffffffffff4
ffffffff813677c4: 41 5c pop %r12
ffffffff813677c6: 31 c0 xor %eax,%eax
ffffffff813677c8: 48 89 45 c8 mov %rax,-0x38(%rbp)
ffffffff813677cc: eb 61 jmp ffffffff8136782f <drm_mode_setcrtc+0x3e3>
ffffffff813677ce: 49 89 c7 mov %rax,%r15

connector_set[i] = connector;
}
}

set.crtc = crtc;
ffffffff813677d1: 4c 89 6d 80 mov %r13,-0x80(%rbp)
set.x = crtc_req->x;
ffffffff813677d5: 41 8b 4e 14 mov 0x14(%r14),%ecx
ffffffff813677d9: 89 4d 90 mov %ecx,-0x70(%rbp)
set.y = crtc_req->y;
ffffffff813677dc: 41 8b 4e 18 mov 0x18(%r14),%ecx
ffffffff813677e0: 89 4d 94 mov %ecx,-0x6c(%rbp)
set.mode = mode;
ffffffff813677e3: 48 8b 45 c0 mov -0x40(%rbp),%rax
ffffffff813677e7: 48 89 45 88 mov %rax,-0x78(%rbp)
set.connectors = connector_set;
ffffffff813677eb: 4c 89 7d 98 mov %r15,-0x68(%rbp)
set.num_connectors = crtc_req->count_connectors;
ffffffff813677ef: 89 d0 mov %edx,%eax
ffffffff813677f1: 48 89 45 a0 mov %rax,-0x60(%rbp)
set.fb = fb;
ffffffff813677f5: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff813677f9: 48 89 85 78 ff ff ff mov %rax,-0x88(%rbp)
ret = __drm_mode_set_config_internal(&set, &ctx);
ffffffff81367800: 48 8d bd 78 ff ff ff lea -0x88(%rbp),%rdi
ffffffff81367807: e8 d6 fa ff ff callq ffffffff813672e2 <__drm_mode_set_config_internal>
ffffffff8136780c: 41 89 c4 mov %eax,%r12d
ffffffff8136780f: eb 1e jmp ffffffff8136782f <drm_mode_setcrtc+0x3e3>
ffffffff81367811: 6a f2 pushq $0xfffffffffffffff2
ffffffff81367813: 41 5c pop %r12
ffffffff81367815: 4c 8b 7d c8 mov -0x38(%rbp),%r15
ffffffff81367819: eb 14 jmp ffffffff8136782f <drm_mode_setcrtc+0x3e3>
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);

mutex_lock(&crtc->dev->mode_config.mutex);
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
ffffffff8136781b: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff8136781f: 48 89 de mov %rbx,%rsi
ffffffff81367822: e8 08 7b 00 00 callq ffffffff8136f32f <drm_modeset_lock_all_ctx>
ffffffff81367827: 41 89 c4 mov %eax,%r12d
if (ret)
ffffffff8136782a: 45 85 e4 test %r12d,%r12d
ffffffff8136782d: 74 16 je ffffffff81367845 <drm_mode_setcrtc+0x3f9>
set.num_connectors = crtc_req->count_connectors;
set.fb = fb;
ret = __drm_mode_set_config_internal(&set, &ctx);

out:
if (fb)
ffffffff8136782f: 48 83 7d d0 00 cmpq $0x0,-0x30(%rbp)
ffffffff81367834: 74 6b je ffffffff813678a1 <drm_mode_setcrtc+0x455>
* This function decrements the framebuffer's reference count and frees the
* framebuffer if the reference count drops to zero.
*/
static inline void drm_framebuffer_put(struct drm_framebuffer *fb)
{
drm_mode_object_put(&fb->base);
ffffffff81367836: 48 8b 45 d0 mov -0x30(%rbp),%rax
ffffffff8136783a: 48 8d 78 18 lea 0x18(%rax),%rdi
ffffffff8136783e: e8 07 db 00 00 callq ffffffff8137534a <drm_mode_object_put>
ffffffff81367843: eb 62 jmp ffffffff813678a7 <drm_mode_setcrtc+0x45b>
drm_modeset_acquire_init(&ctx, 0);
retry:
ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
if (ret)
goto out;
if (crtc_req->mode_valid) {
ffffffff81367845: 41 83 7e 20 00 cmpl $0x0,0x20(%r14)
ffffffff8136784a: 0f 84 a0 fd ff ff je ffffffff813675f0 <drm_mode_setcrtc+0x1a4>
/* If we have a mode we need a framebuffer. */
/* If we pass -1, set the mode with the currently bound fb */
if (crtc_req->fb_id == -1) {
ffffffff81367850: 41 8b 76 10 mov 0x10(%r14),%esi
ffffffff81367854: 83 fe ff cmp $0xffffffff,%esi
ffffffff81367857: 0f 84 db fc ff ff je ffffffff81367538 <drm_mode_setcrtc+0xec>
ffffffff8136785d: 48 8b 5d b0 mov -0x50(%rbp),%rbx
}
fb = crtc->primary->fb;
/* Make refcounting symmetric with the lookup path. */
drm_framebuffer_get(fb);
} else {
fb = drm_framebuffer_lookup(dev, crtc_req->fb_id);
ffffffff81367861: 48 89 df mov %rbx,%rdi
ffffffff81367864: e8 64 b3 00 00 callq ffffffff81372bcd <drm_framebuffer_lookup>
ffffffff81367869: 48 89 c1 mov %rax,%rcx
if (!fb) {
ffffffff8136786c: 48 89 4d d0 mov %rcx,-0x30(%rbp)
ffffffff81367870: 48 85 c0 test %rax,%rax
ffffffff81367873: 0f 85 eb fc ff ff jne ffffffff81367564 <drm_mode_setcrtc+0x118>
DRM_DEBUG_KMS("Unknown FB ID%d\n",
ffffffff81367879: 41 8b 4e 10 mov 0x10(%r14),%ecx
ffffffff8136787d: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff81367884: 48 c7 c2 fb 7a 9b 81 mov $0xffffffff819b7afb,%rdx
ffffffff8136788b: 31 c0 xor %eax,%eax
ffffffff8136788d: 6a 04 pushq $0x4
ffffffff8136788f: 5e pop %rsi
ffffffff81367890: e8 8d c2 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff81367895: 31 c0 xor %eax,%eax
ffffffff81367897: 48 89 45 d0 mov %rax,-0x30(%rbp)
ffffffff8136789b: 6a fe pushq $0xfffffffffffffffe
ffffffff8136789d: 41 5c pop %r12
ffffffff8136789f: eb 06 jmp ffffffff813678a7 <drm_mode_setcrtc+0x45b>
ffffffff813678a1: 31 c0 xor %eax,%eax
ffffffff813678a3: 48 89 45 d0 mov %rax,-0x30(%rbp)

out:
if (fb)
drm_framebuffer_put(fb);

if (connector_set) {
ffffffff813678a7: 4d 85 ff test %r15,%r15
ffffffff813678aa: 74 27 je ffffffff813678d3 <drm_mode_setcrtc+0x487>
ffffffff813678ac: 31 db xor %ebx,%ebx
ffffffff813678ae: eb 17 jmp ffffffff813678c7 <drm_mode_setcrtc+0x47b>
for (i = 0; i < crtc_req->count_connectors; i++) {
if (connector_set[i])
ffffffff813678b0: 48 63 c3 movslq %ebx,%rax
ffffffff813678b3: 49 8b 3c c7 mov (%r15,%rax,8),%rdi
ffffffff813678b7: 48 85 ff test %rdi,%rdi
ffffffff813678ba: 74 09 je ffffffff813678c5 <drm_mode_setcrtc+0x479>
* This function decrements the connector's reference count and frees the
* object if the reference count drops to zero.
*/
static inline void drm_connector_put(struct drm_connector *connector)
{
drm_mode_object_put(&connector->base);
ffffffff813678bc: 48 83 c7 28 add $0x28,%rdi
ffffffff813678c0: e8 85 da 00 00 callq ffffffff8137534a <drm_mode_object_put>
out:
if (fb)
drm_framebuffer_put(fb);

if (connector_set) {
for (i = 0; i < crtc_req->count_connectors; i++) {
ffffffff813678c5: ff c3 inc %ebx
ffffffff813678c7: 41 3b 5e 08 cmp 0x8(%r14),%ebx
ffffffff813678cb: 72 e3 jb ffffffff813678b0 <drm_mode_setcrtc+0x464>
ffffffff813678cd: 4c 8b 6d b8 mov -0x48(%rbp),%r13
ffffffff813678d1: eb 03 jmp ffffffff813678d6 <drm_mode_setcrtc+0x48a>
ffffffff813678d3: 45 31 ff xor %r15d,%r15d
if (connector_set[i])
drm_connector_put(connector_set[i]);
}
}
kfree(connector_set);
ffffffff813678d6: 48 8b 7d c8 mov -0x38(%rbp),%rdi
ffffffff813678da: e8 af 78 dd ff callq ffffffff8113f18e <kfree>
drm_mode_destroy(dev, mode);
ffffffff813678df: 48 8b 7d b0 mov -0x50(%rbp),%rdi
ffffffff813678e3: 48 8b 75 c0 mov -0x40(%rbp),%rsi
ffffffff813678e7: e8 ef 04 00 00 callq ffffffff81367ddb <drm_mode_destroy>
if (ret == -EDEADLK) {
ffffffff813678ec: 41 83 fc dd cmp $0xffffffdd,%r12d
ffffffff813678f0: 0f 84 2e fc ff ff je ffffffff81367524 <drm_mode_setcrtc+0xd8>
ffffffff813678f6: 4c 8d b5 40 ff ff ff lea -0xc0(%rbp),%r14
drm_modeset_backoff(&ctx);
goto retry;
}
drm_modeset_drop_locks(&ctx);
ffffffff813678fd: 4c 89 f7 mov %r14,%rdi
ffffffff81367900: e8 62 7b 00 00 callq ffffffff8136f467 <drm_modeset_drop_locks>
drm_modeset_acquire_fini(&ctx);
ffffffff81367905: 4c 89 f7 mov %r14,%rdi
ffffffff81367908: e8 ad 7a 00 00 callq ffffffff8136f3ba <drm_modeset_acquire_fini>
mutex_unlock(&crtc->dev->mode_config.mutex);
ffffffff8136790d: 49 8b 7d 00 mov 0x0(%r13),%rdi
ffffffff81367911: 48 81 c7 b0 02 00 00 add $0x2b0,%rdi
ffffffff81367918: e8 fb 37 2e 00 callq ffffffff8164b118 <mutex_unlock>
ffffffff8136791d: eb 20 jmp ffffffff8136793f <drm_mode_setcrtc+0x4f3>
if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;

crtc = drm_crtc_find(dev, crtc_req->crtc_id);
if (!crtc) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
ffffffff8136791f: 41 8b 4e 0c mov 0xc(%r14),%ecx
ffffffff81367923: 6a 04 pushq $0x4
ffffffff81367925: 5e pop %rsi
ffffffff81367926: 48 c7 c7 4d 82 95 81 mov $0xffffffff8195824d,%rdi
ffffffff8136792d: 48 c7 c2 c9 7a 9b 81 mov $0xffffffff819b7ac9,%rdx
ffffffff81367934: 31 c0 xor %eax,%eax
ffffffff81367936: e8 e7 c1 ff ff callq ffffffff81363b22 <drm_printk>
ffffffff8136793b: 6a fe pushq $0xfffffffffffffffe
ffffffff8136793d: 41 5c pop %r12
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
mutex_unlock(&crtc->dev->mode_config.mutex);

return ret;
}
ffffffff8136793f: 44 89 e0 mov %r12d,%eax
ffffffff81367942: 48 81 c4 b8 00 00 00 add $0xb8,%rsp
ffffffff81367949: 5b pop %rbx
ffffffff8136794a: 41 5c pop %r12
ffffffff8136794c: 41 5d pop %r13
ffffffff8136794e: 41 5e pop %r14
ffffffff81367950: 41 5f pop %r15
ffffffff81367952: 5d pop %rbp
ffffffff81367953: c3 retq

============================================================

Double fault with f05058c4d652:

[ 3.798722] PANIC: double fault, error_code: 0x0
[ 3.807387] CPU: 1 PID: 605 Comm: frecon Not tainted 4.12.0-00023-g711d82c128ff #107
[ 3.816040] Hardware name: GOOGLE Squawks, BIOS Google_Squawks.5216.152.76 03/04/2016
[ 3.824792] task: ffff880075b92f00 task.stack: ffffc90000d6c000
[ 3.829599] EXT4-fs (mmcblk0p1): re-mounted. Opts: commit=600,data=ordered
[ 3.839092] RIP: 0010:drm_mode_setcrtc+0x328/0x51f
[ 3.844443] RSP: 0018:0000000000000000 EFLAGS: 00010206
[ 3.850280] RAX: 0000559e707c4d60 RBX: 0000000000000000 RCX: 0000000000000008
[ 3.858253] RDX: 0000000000000001 RSI: ffffc90000d6fcc8 RDI: ffffffff81367805
[ 3.866225] RBP: ffffc90000d6fd90 R08: 00000000014000c0 R09: 0000000000000308
[ 3.874199] R10: 0000000000000300 R11: 0000000000000556 R12: 0000000000000000
[ 3.882163] R13: ffff880077a25000 R14: ffffc90000d6fdd0 R15: 0000000000000000
[ 3.890136] FS: 00007fb2dbd62740(0000) GS:ffff88007ad00000(0000) knlGS:0000000000000000
[ 3.899177] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3.905595] CR2: fffffffffffffff8 CR3: 000000007596b000 CR4: 00000000001006e0
[ 3.913568] Call Trace:
[ 3.916296] Code: b8 48 8d b5 38 ff ff ff 41 8b 56 08 39 d3 0f 83 85 00 00 00 4c 63 fb 4a 83 24 f8 00 4a 8d 04 bd 00 00 00 00 49 03 06 48 8b 65 a8 <e8> 73 26 f1 ff 49 89 d4 48 89 65 a8 85 c0 0f 85 a0 00 00 00 ba
[ 3.937440] Kernel panic - not syncing: Machine halted.
[ 3.943268] CPU: 1 PID: 605 Comm: frecon Not tainted 4.12.0-00023-g711d82c128ff #107
[ 3.951921] Hardware name: GOOGLE Squawks, BIOS Google_Squawks.5216.152.76 03/04/2016
[ 3.960671] Call Trace:
[ 3.963398] <#DF>
[ 3.965637] __dump_stack+0x19/0x1b
[ 3.969531] dump_stack+0x42/0x60
[ 3.969541] PANIC: double fault, error_code: 0x0
[ 3.969545] CPU: 0 PID: 719 Comm: rsyslogd Not tainted 4.12.0-00023-g711d82c128ff #107
[ 3.969546] Hardware name: GOOGLE Squawks, BIOS Google_Squawks.5216.152.76 03/04/2016
[ 3.969548] task: ffff880075210000 task.stack: ffffc90000554000
[ 3.969554] RIP: 0010:SyS_setgroups+0x6b/0xd4
[ 3.969556] RSP: 0018:ffffffff8106360d EFLAGS: 00010297
[ 3.969558] RAX: 0000558afd6664e0 RBX: 0000000000000000 RCX: 0000000000000001
[ 3.969559] RDX: 000000000000000c RSI: 0000000000000000 RDI: ffffffff8106360d
[ 3.969560] RBP: ffffc90000557f48 R08: ffffffffffffffea R09: ffffc90000557e50
[ 3.969562] R10: 00007fb4acc1d0d0 R11: ffff880075210000 R12: 0000558afd6664e0
[ 3.969563] R13: 00007fb4acdf9780 R14: fffffffffffffff2 R15: ffff880076d13f50
[ 3.969565] FS: 00007fb4acdf9780(0000) GS:ffff88007ac00000(0000) knlGS:0000000000000000
[ 3.969566] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3.969568] CR2: ffffffff810635f8 CR3: 00000000751fb000 CR4: 00000000001006f0
[ 3.969569] Call Trace:
[ 3.969571] Code: 5d c3 89 df e8 9c fd ff ff 49 89 c7 4d 85 ff 74 5b 41 8b 4f 04 31 f6 6a f2 41 5e 6a ea 41 58 eb 22 48 63 de 49 8d 04 9c 48 89 fc <e8> 7c 66 21 00 85 c0 75 41 83 fa ff 74 39 48 89 e7 41 89 54 9f
[ 4.100376] panic+0xf0/0x23e
[ 4.103688] df_debug+0x31/0x31
[ 4.107193] do_double_fault+0xd8/0xfb
[ 4.111379] double_fault+0x22/0x30
[ 4.115274] RIP: 0010:drm_mode_setcrtc+0x328/0x51f
[ 4.120624] RSP: 0018:0000000000000000 EFLAGS: 00010206
[ 4.126451] RAX: 0000559e707c4d60 RBX: 0000000000000000 RCX: 0000000000000008
[ 4.134424] RDX: 0000000000000001 RSI: ffffc90000d6fcc8 RDI: ffffffff81367805
[ 4.142397] RBP: ffffc90000d6fd90 R08: 00000000014000c0 R09: 0000000000000308
[ 4.150369] R10: 0000000000000300 R11: 0000000000000556 R12: 0000000000000000
[ 4.158341] R13: ffff880077a25000 R14: ffffc90000d6fdd0 R15: 0000000000000000
[ 4.166316] ? drm_mode_setcrtc+0x2b5/0x51f
[ 4.170988] WARNING: kernel stack regs at ffff88007ad05f58 in frecon:605 has bad 'bp' value ffffc90000d6fd90
[ 4.170990] unwind stack type:0 next_sp: (null) mask:0x10 graph_idx:0
[ 4.170993] ffff88007ad05d40: ffff88007ad05e20 (0xffff88007ad05e20)
[ 4.170995] ffff88007ad05d48: ffffffff810184b0 (show_trace_log_lvl+0x163/0x23a)
[ 4.170996] ffff88007ad05d50: 0000000000000000 ...
[ 4.170998] ffff88007ad05d58: ffff88007ad05000 (0xffff88007ad05000)
[ 4.170999] ffff88007ad05d60: ffff88007ad06000 (0xffff88007ad06000)
[ 4.171000] ffff88007ad05d68: 0000000000000000 ...
[ 4.171001] ffff88007ad05d70: 0000000000000010 (0x10)
[ 4.171003] ffff88007ad05d78: ffff880075b92f00 (0xffff880075b92f00)
[ 4.171004] ffff88007ad05d80: 0000010100000000 (0x10100000000)
[ 4.171005] ffff88007ad05d88: 0000000000000000 ...
[ 4.171006] ffff88007ad05d90: ffff88007ad05d40 (0xffff88007ad05d40)
[ 4.171008] ffff88007ad05d98: ffff88007ad05f58 (0xffff88007ad05f58)
[ 4.171010] ffff88007ad05da0: ffffffff81367878 (drm_mode_setcrtc+0x328/0x51f)
[ 4.171011] ffff88007ad05da8: 0000000000000004 (0x4)
[ 4.171013] ffff88007ad05db0: ffff88007ad05000 (0xffff88007ad05000)
[ 4.171014] ffff88007ad05db8: ffff88007ad06000 (0xffff88007ad06000)
[ 4.171015] ffff88007ad05dc0: 0000000000000000 ...
[ 4.171016] ffff88007ad05dc8: 0000000000000010 (0x10)
[ 4.171018] ffff88007ad05dd0: ffff88007ad05f58 (0xffff88007ad05f58)
[ 4.171019] ffff88007ad05dd8: ffff880075b92f00 (0xffff880075b92f00)
[ 4.171020] ffff88007ad05de0: ffffffff8195ba29 (0xffffffff8195ba29)
[ 4.171022] ffff88007ad05de8: 0000000081e70fc0 (0x81e70fc0)
[ 4.171023] ffff88007ad05df0: ffffffff8195b9f9 (0xffffffff8195b9f9)
[ 4.171024] ffff88007ad05df8: 0000000000000086 (0x86)
[ 4.171025] ffff88007ad05e00: 0000000000000000 ...
[ 4.171027] ffff88007ad05e08: ffff880077a25000 (0xffff880077a25000)
[ 4.171028] ffff88007ad05e10: ffff88007ad05f00 (0xffff88007ad05f00)
[ 4.171029] ffff88007ad05e18: ffff880075b92f00 (0xffff880075b92f00)
[ 4.171031] ffff88007ad05e20: ffff88007ad05e30 (0xffff88007ad05e30)
[ 4.171033] ffff88007ad05e28: ffffffff81018647 (show_stack+0x45/0x47)
[ 4.171034] ffff88007ad05e30: ffff88007ad05e40 (0xffff88007ad05e40)
[ 4.171038] ffff88007ad05e38: ffffffff8126f18f (__dump_stack+0x19/0x1b)
[ 4.171039] ffff88007ad05e40: ffff88007ad05e70 (0xffff88007ad05e70)
[ 4.171042] ffff88007ad05e48: ffffffff8126f158 (dump_stack+0x42/0x60)
[ 4.171043] ffff88007ad05e50: 0000000000000086 (0x86)
[ 4.171044] ffff88007ad05e58: 0000000000000000 ...
[ 4.171045] ffff88007ad05e60: 0000000200000000 (0x200000000)
[ 4.171046] ffff88007ad05e68: ffffffff819641ff (0xffffffff819641ff)
[ 4.171048] ffff88007ad05e70: ffff88007ad05f08 (0xffff88007ad05f08)
[ 4.171050] ffff88007ad05e78: ffffffff81047bea (panic+0xf0/0x23e)
[ 4.171051] ffff88007ad05e80: ffff88007ad05e90 (0xffff88007ad05e90)
[ 4.171052] ffff88007ad05e88: 000000007596b000 (0x7596b000)
[ 4.171054] ffff88007ad05e90: 00000000001006e0 (0x1006e0)
[ 4.171055] ffff88007ad05e98: 0000000000000002 (0x2)
[ 4.171056] ffff88007ad05ea0: 0000000000000000 ...
[ 4.171057] ffff88007ad05ea8: ffffffff81c42180 (0xffffffff81c42180)
[ 4.171058] ffff88007ad05eb0: 0000000200000000 (0x200000000)
[ 4.171060] ffff88007ad05eb8: 00000000ffff0a30 (0xffff0a30)
[ 4.171061] ffff88007ad05ec0: 0000003000000008 (0x3000000008)
[ 4.171062] ffff88007ad05ec8: ffff88007ad05f18 (0xffff88007ad05f18)
[ 4.171064] ffff88007ad05ed0: ffff88007ad05e90 (0xffff88007ad05e90)
[ 4.171065] ffff88007ad05ed8: ba00000000000024 (0xba00000000000024)
[ 4.171066] ffff88007ad05ee0: ffff88007ad05f58 (0xffff88007ad05f58)
[ 4.171067] ffff88007ad05ee8: 0000000000000000 ...
[ 4.171069] ffff88007ad05ef0: ffff880077a25000 (0xffff880077a25000)
[ 4.171070] ffff88007ad05ef8: ffff88007ad05f58 (0xffff88007ad05f58)
[ 4.171071] ffff88007ad05f00: ffff880075b92f00 (0xffff880075b92f00)
[ 4.171073] ffff88007ad05f08: ffff88007ad05f20 (0xffff88007ad05f20)
[ 4.171075] ffff88007ad05f10: ffffffff81037185 (df_debug+0x31/0x31)
[ 4.171075] ffff88007ad05f18: 0000000000000000 ...
[ 4.171077] ffff88007ad05f20: ffff88007ad05f48 (0xffff88007ad05f48)
[ 4.171079] ffff88007ad05f28: ffffffff81016626 (do_double_fault+0xd8/0xfb)
[ 4.171080] ffff88007ad05f30: 0000000000000001 (0x1)
[ 4.171082] ffff88007ad05f38: ffffc90000d6fdd0 (0xffffc90000d6fdd0)
[ 4.171082] ffff88007ad05f40: 0000000000000000 ...
[ 4.171084] ffff88007ad05f48: ffff88007ad05f59 (0xffff88007ad05f59)
[ 4.171086] ffff88007ad05f50: ffffffff8164df72 (double_fault+0x22/0x30)
[ 4.171087] ffff88007ad05f58: 0000000000000000 ...
[ 4.171088] ffff88007ad05f60: ffffc90000d6fdd0 (0xffffc90000d6fdd0)
[ 4.171090] ffff88007ad05f68: ffff880077a25000 (0xffff880077a25000)
[ 4.171091] ffff88007ad05f70: 0000000000000000 ...
[ 4.171092] ffff88007ad05f78: ffffc90000d6fd90 (0xffffc90000d6fd90)
[ 4.171093] ffff88007ad05f80: 0000000000000000 ...
[ 4.171094] ffff88007ad05f88: 0000000000000556 (0x556)
[ 4.171095] ffff88007ad05f90: 0000000000000300 (0x300)
[ 4.171096] ffff88007ad05f98: 0000000000000308 (0x308)
[ 4.171098] ffff88007ad05fa0: 00000000014000c0 (0x14000c0)
[ 4.171099] ffff88007ad05fa8: 0000559e707c4d60 (0x559e707c4d60)
[ 4.171100] ffff88007ad05fb0: 0000000000000008 (0x8)
[ 4.171101] ffff88007ad05fb8: 0000000000000001 (0x1)
[ 4.171103] ffff88007ad05fc0: ffffc90000d6fcc8 (0xffffc90000d6fcc8)
[ 4.171105] ffff88007ad05fc8: ffffffff81367805 (drm_mode_setcrtc+0x2b5/0x51f)
[ 4.171107] ffff88007ad05fd0: ffffffffffffffff (0xffffffffffffffff)
[ 4.171109] ffff88007ad05fd8: ffffffff81367878 (drm_mode_setcrtc+0x328/0x51f)
[ 4.171110] ffff88007ad05fe0: 0000000000000010 (0x10)
[ 4.171111] ffff88007ad05fe8: 0000000000010206 (0x10206)
[ 4.171112] ffff88007ad05ff0: 0000000000000000 ...
[ 4.171114] ffff88007ad05ff8: 0000000000000018 (0x18)
[ 4.171115] </#DF>
[ 5.819749] Shutting down cpus with NMI
[ 5.824035] Kernel Offset: disabled
[ 5.827930] ACPI MEMORY or I/O RESET_REG.