Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lib/fonts: Compare font data for equality with font_data_is_equal()

Add font_data_is_equal() and update consoles to use it.

Font data is equal if it has the same size and contains the same values
on all bytes. Only fbcon uses a crc32 checksum. If set in both operands
the checksums have to be equal.

The new helper also guarantees to not compare internal fonts against
fonts from user space. Internal fonts cannot be ref-counted, so making
them equal to user-space fonts with the same byte sequence results in
undefined behavior.

The test only compares data buffers. Their interpretation is up each
console. Therefore remove a width test in fbcon_set_font().

v3:
- rebase onto font_data_{get,put}()

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>

authored by

Thomas Zimmermann and committed by
Helge Deller
1e3c49aa 1de371b1

+29 -9
+1 -3
drivers/video/console/newport_con.c
··· 529 529 530 530 /* check if font is already used by other console */ 531 531 for (i = 0; i < MAX_NR_CONSOLES; i++) { 532 - if (font_data[i] != FONT_DATA 533 - && font_data_size(font_data[i]) == size 534 - && !memcmp(font_data[i], new_data, size)) { 532 + if (font_data_is_equal(font_data[i], new_data)) { 535 533 font_data_put(new_data); 536 534 /* current font is the same as the new one */ 537 535 if (i == unit)
+1 -6
drivers/video/fbdev/core/fbcon.c
··· 2540 2540 FNTSUM(new_data) = csum; 2541 2541 /* Check if the same font is on some other console already */ 2542 2542 for (i = first_fb_vc; i <= last_fb_vc; i++) { 2543 - struct vc_data *tmp = vc_cons[i].d; 2544 - 2545 2543 if (fb_display[i].fontdata && 2546 - FNTSUM(fb_display[i].fontdata) == csum && 2547 - font_data_size(fb_display[i].fontdata) == size && 2548 - tmp->vc_font.width == w && 2549 - !memcmp(fb_display[i].fontdata, new_data, size)) { 2544 + font_data_is_equal(fb_display[i].fontdata, new_data)) { 2550 2545 font_data_get(fb_display[i].fontdata); 2551 2546 font_data_put(new_data); 2552 2547 new_data = fb_display[i].fontdata;
+1
include/linux/font.h
··· 57 57 void font_data_get(font_data_t *fd); 58 58 bool font_data_put(font_data_t *fd); 59 59 unsigned int font_data_size(font_data_t *fd); 60 + bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs); 60 61 61 62 /* 62 63 * Font description
+26
lib/fonts/fonts.c
··· 110 110 } 111 111 EXPORT_SYMBOL_GPL(font_data_size); 112 112 113 + /** 114 + * font_data_is_equal - Compares font data for equality 115 + * @lhs: Left-hand side font data 116 + * @rhs: Right-hand-size font data 117 + * 118 + * Font data is equal if is constain the same sequence of values. The 119 + * helper also use the checksum, if both arguments contain it. Font data 120 + * coming from different origins, internal or from user space, is never 121 + * equal. Allowing this would break reference counting. 122 + * 123 + * Returns: 124 + * True if the given font data is equal, false otherwise. 125 + */ 126 + bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs) 127 + { 128 + if (font_data_is_internal(lhs) != font_data_is_internal(rhs)) 129 + return false; 130 + if (font_data_size(lhs) != font_data_size(rhs)) 131 + return false; 132 + if (FNTSUM(lhs) && FNTSUM(rhs) && FNTSUM(lhs) != FNTSUM(rhs)) 133 + return false; 134 + 135 + return !memcmp(lhs, rhs, FNTSIZE(lhs)); 136 + } 137 + EXPORT_SYMBOL_GPL(font_data_is_equal); 138 + 113 139 /* 114 140 * Font lookup 115 141 */