diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index dbbb787fc46e..db0228bce00e 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -529,9 +529,7 @@ static int newport_set_font(int unit, const struct console_font *op, /* check if font is already used by other console */ for (i = 0; i < MAX_NR_CONSOLES; i++) { - if (font_data[i] != FONT_DATA - && font_data_size(font_data[i]) == size - && !memcmp(font_data[i], new_data, size)) { + if (font_data_is_equal(font_data[i], new_data)) { font_data_put(new_data); /* current font is the same as the new one */ if (i == unit) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index ac59480c98cb..00255ac92e42 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2540,13 +2540,8 @@ static int fbcon_set_font(struct vc_data *vc, const struct console_font *font, FNTSUM(new_data) = csum; /* Check if the same font is on some other console already */ for (i = first_fb_vc; i <= last_fb_vc; i++) { - struct vc_data *tmp = vc_cons[i].d; - if (fb_display[i].fontdata && - FNTSUM(fb_display[i].fontdata) == csum && - font_data_size(fb_display[i].fontdata) == size && - tmp->vc_font.width == w && - !memcmp(fb_display[i].fontdata, new_data, size)) { + font_data_is_equal(fb_display[i].fontdata, new_data)) { font_data_get(fb_display[i].fontdata); font_data_put(new_data); new_data = fb_display[i].fontdata; diff --git a/include/linux/font.h b/include/linux/font.h index dd319d0f0201..58bf3c64cabb 100644 --- a/include/linux/font.h +++ b/include/linux/font.h @@ -57,6 +57,7 @@ static inline const unsigned char *font_data_buf(font_data_t *fd) void font_data_get(font_data_t *fd); bool font_data_put(font_data_t *fd); unsigned int font_data_size(font_data_t *fd); +bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs); /* * Font description diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c index d25efd8d6c31..3fb76d185647 100644 --- a/lib/fonts/fonts.c +++ b/lib/fonts/fonts.c @@ -110,6 +110,32 @@ unsigned int font_data_size(font_data_t *fd) } EXPORT_SYMBOL_GPL(font_data_size); +/** + * font_data_is_equal - Compares font data for equality + * @lhs: Left-hand side font data + * @rhs: Right-hand-size font data + * + * Font data is equal if is constain the same sequence of values. The + * helper also use the checksum, if both arguments contain it. Font data + * coming from different origins, internal or from user space, is never + * equal. Allowing this would break reference counting. + * + * Returns: + * True if the given font data is equal, false otherwise. + */ +bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs) +{ + if (font_data_is_internal(lhs) != font_data_is_internal(rhs)) + return false; + if (font_data_size(lhs) != font_data_size(rhs)) + return false; + if (FNTSUM(lhs) && FNTSUM(rhs) && FNTSUM(lhs) != FNTSUM(rhs)) + return false; + + return !memcmp(lhs, rhs, FNTSIZE(lhs)); +} +EXPORT_SYMBOL_GPL(font_data_is_equal); + /* * Font lookup */