• Linus Torvalds's avatar
    drm: fix EDID struct for old ARM OABI format · 47f15561
    Linus Torvalds authored
    When building the kernel for arm with the "-mabi=apcs-gnu" option, gcc
    will force alignment of all structures and unions to a word boundary
    (see also STRUCTURE_SIZE_BOUNDARY and the "-mstructure-size-boundary=XX"
    option if you're a gcc person), even when the members of said structures
    do not want or need said alignment.
    
    This completely messes up the structure alignment of 'struct edid' on
    those targets, because even though all the embedded structures are
    marked with "__attribute__((packed))", the unions that contain them are
    not.
    
    This was exposed by commit f1e4c916 ("drm/edid: add EDID block count
    and size helpers"), but the bug is pre-existing.  That commit just made
    the structure layout problem cause a build failure due to the addition
    of the
    
            BUILD_BUG_ON(sizeof(*edid) != EDID_LENGTH);
    
    sanity check in drivers/gpu/drm/drm_edid.c:edid_block_data().
    
    This legacy union alignment should probably not be used in the first
    place, but we can fix the layout by adding the packed attribute to the
    union entries even when each member is already packed and it shouldn't
    matter in a sane build environment.
    
    You can see this issue with a trivial test program:
    
      union {
    	struct {
    		char c[5];
    	};
    	struct {
    		char d;
    		unsigned e;
    	} __attribute__((packed));
      } a = { "1234" };
    
    where building this with a normal "gcc -S" will result in the expected
    5-byte size of said union:
    
    	.type	a, @object
    	.size	a, 5
    
    but with an ARM compiler and the old ABI:
    
        arm-linux-gnu-gcc -mabi=apcs-gnu -mfloat-abi=soft -S t.c
    
    you get
    
    	.type	a, %object
    	.size	a, 8
    
    instead, because even though each member of the union is packed, the
    union itself still gets aligned.
    
    This was reported by Sudip for the spear3xx_defconfig target.
    
    Link: https://lore.kernel.org/lkml/YpCUzStDnSgQLNFN@debian/Reported-by: default avatarSudip Mukherjee <sudipm.mukherjee@gmail.com>
    Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
    Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
    Cc: Maxime Ripard <mripard@kernel.org>
    Cc: Thomas Zimmermann <tzimmermann@suse.de>
    Cc: David Airlie <airlied@linux.ie>
    Cc: Daniel Vetter <daniel@ffwll.ch>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    47f15561
drm_edid.h 18.4 KB