--- zzzz-none-000/linux-3.10.107/drivers/tty/vt/consolemap.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/tty/vt/consolemap.c 2021-02-04 17:41:59.000000000 +0000 @@ -179,7 +179,6 @@ unsigned long sum; unsigned char *inverse_translations[4]; u16 *inverse_trans_unicode; - int readonly; }; static struct uni_pagedir *dflt; @@ -262,19 +261,22 @@ int m; if (glyph < 0 || glyph >= MAX_GLYPH) return 0; - else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc)) - return glyph; - else if (use_unicode) { - if (!p->inverse_trans_unicode) + else { + p = *conp->vc_uni_pagedir_loc; + if (!p) return glyph; - else - return p->inverse_trans_unicode[glyph]; - } else { - m = inv_translate[conp->vc_num]; - if (!p->inverse_translations[m]) - return glyph; - else - return p->inverse_translations[m][glyph]; + else if (use_unicode) { + if (!p->inverse_trans_unicode) + return glyph; + else + return p->inverse_trans_unicode[glyph]; + } else { + m = inv_translate[conp->vc_num]; + if (!p->inverse_translations[m]) + return glyph; + else + return p->inverse_translations[m][glyph]; + } } } EXPORT_SYMBOL_GPL(inverse_translate); @@ -287,7 +289,7 @@ for (i = 0; i < MAX_NR_CONSOLES; i++) { if (!vc_cons_allocated(i)) continue; - p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc; + p = *vc_cons[i].d->vc_uni_pagedir_loc; if (p && p != q) { set_inverse_transl(vc_cons[i].d, p, USER_MAP); set_inverse_trans_unicode(vc_cons[i].d, p); @@ -398,7 +400,8 @@ if (p == dflt) dflt = NULL; for (i = 0; i < 32; i++) { - if ((p1 = p->uni_pgdir[i]) != NULL) { + p1 = p->uni_pgdir[i]; + if (p1 != NULL) { for (j = 0; j < 32; j++) kfree(p1[j]); kfree(p1); @@ -418,10 +421,10 @@ { struct uni_pagedir *p; - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + p = *vc->vc_uni_pagedir_loc; if (!p) return; - *vc->vc_uni_pagedir_loc = 0; + *vc->vc_uni_pagedir_loc = NULL; if (--p->refcount) return; con_release_unimap(p); @@ -436,7 +439,7 @@ for (i = 0; i < MAX_NR_CONSOLES; i++) { if (!vc_cons_allocated(i)) continue; - q = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc; + q = *vc_cons[i].d->vc_uni_pagedir_loc; if (!q || q == p || q->sum != p->sum) continue; for (j = 0; j < 32; j++) { @@ -459,7 +462,7 @@ } if (j == 32) { q->refcount++; - *conp->vc_uni_pagedir_loc = (unsigned long)q; + *conp->vc_uni_pagedir_loc = q; con_release_unimap(p); kfree(p); return 1; @@ -474,14 +477,16 @@ int i, n; u16 **p1, *p2; - if (!(p1 = p->uni_pgdir[n = unicode >> 11])) { + p1 = p->uni_pgdir[n = unicode >> 11]; + if (!p1) { p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL); if (!p1) return -ENOMEM; for (i = 0; i < 32; i++) p1[i] = NULL; } - if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) { + p2 = p1[n = (unicode >> 6) & 0x1f]; + if (!p2) { p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL); if (!p2) return -ENOMEM; memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */ @@ -500,10 +505,7 @@ { struct uni_pagedir *p, *q; - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; - if (p && p->readonly) - return -EIO; - + p = *vc->vc_uni_pagedir_loc; if (!p || --p->refcount) { q = kzalloc(sizeof(*p), GFP_KERNEL); if (!q) { @@ -512,7 +514,7 @@ return -ENOMEM; } q->refcount=1; - *vc->vc_uni_pagedir_loc = (unsigned long)q; + *vc->vc_uni_pagedir_loc = q; } else { if (p == dflt) dflt = NULL; p->refcount++; @@ -536,18 +538,18 @@ int err = 0, err1, i; struct uni_pagedir *p, *q; + if (!ct) + return 0; + console_lock(); /* Save original vc_unipagdir_loc in case we allocate a new one */ - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; - if (p->readonly) { - console_unlock(); - return -EIO; - } - - if (!ct) { - console_unlock(); - return 0; + p = *vc->vc_uni_pagedir_loc; + + if (!p) { + err = -EINVAL; + + goto out_unlock; } if (p->refcount > 1) { @@ -564,7 +566,7 @@ * Since refcount was > 1, con_clear_unimap() allocated a * a new uni_pagedir for this vc. Re: p != q */ - q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + q = *vc->vc_uni_pagedir_loc; /* * uni_pgdir is a 32*32*64 table with rows allocated @@ -573,10 +575,12 @@ * entries from "p" (old) to "q" (new). */ l = 0; /* unicode value */ - for (i = 0; i < 32; i++) - if ((p1 = p->uni_pgdir[i])) - for (j = 0; j < 32; j++) - if ((p2 = p1[j])) { + for (i = 0; i < 32; i++) { + p1 = p->uni_pgdir[i]; + if (p1) + for (j = 0; j < 32; j++) { + p2 = p1[j]; + if (p2) { for (k = 0; k < 64; k++, l++) if (p2[k] != 0xffff) { /* @@ -586,7 +590,7 @@ err1 = con_insert_unipair(q, l, p2[k]); if (err1) { p->refcount++; - *vc->vc_uni_pagedir_loc = (unsigned long)p; + *vc->vc_uni_pagedir_loc = p; con_release_unimap(q); kfree(q); console_unlock(); @@ -597,9 +601,11 @@ /* Account for row of 64 empty entries */ l += 64; } + } else /* Account for empty table */ l += 32 * 64; + } /* * Finished copying font table, set vc_uni_pagedir to new table @@ -633,6 +639,7 @@ set_inverse_transl(vc, p, i); /* Update inverse translations */ set_inverse_trans_unicode(vc, p); +out_unlock: console_unlock(); return err; } @@ -655,12 +662,12 @@ struct uni_pagedir *p; if (dflt) { - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + p = *vc->vc_uni_pagedir_loc; if (p == dflt) return 0; dflt->refcount++; - *vc->vc_uni_pagedir_loc = (unsigned long)dflt; + *vc->vc_uni_pagedir_loc = dflt; if (p && !--p->refcount) { con_release_unimap(p); kfree(p); @@ -674,7 +681,7 @@ if (err) return err; - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + p = *vc->vc_uni_pagedir_loc; q = dfont_unitable; for (i = 0; i < 256; i++) @@ -685,7 +692,7 @@ } if (con_unify_unimap(vc, p)) { - dflt = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; + dflt = *vc->vc_uni_pagedir_loc; return err; } @@ -713,9 +720,9 @@ if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc) return 0; con_free_unimap(dst_vc); - q = (struct uni_pagedir *)*src_vc->vc_uni_pagedir_loc; + q = *src_vc->vc_uni_pagedir_loc; q->refcount++; - *dst_vc->vc_uni_pagedir_loc = (long)q; + *dst_vc->vc_uni_pagedir_loc = q; return 0; } EXPORT_SYMBOL(con_copy_unimap); @@ -737,11 +744,13 @@ ect = 0; if (*vc->vc_uni_pagedir_loc) { - p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc; - for (i = 0; i < 32; i++) - if ((p1 = p->uni_pgdir[i])) - for (j = 0; j < 32; j++) - if ((p2 = *(p1++))) + p = *vc->vc_uni_pagedir_loc; + for (i = 0; i < 32; i++) { + p1 = p->uni_pgdir[i]; + if (p1) + for (j = 0; j < 32; j++) { + p2 = *(p1++); + if (p2) for (k = 0; k < 64; k++) { if (*p2 < MAX_GLYPH && ect++ < ct) { __put_user((u_short)((i<<11)+(j<<6)+k), @@ -752,6 +761,8 @@ } p2++; } + } + } } __put_user(ect, uct); console_unlock(); @@ -810,7 +821,7 @@ if (!*conp->vc_uni_pagedir_loc) return -3; - p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc; + p = *conp->vc_uni_pagedir_loc; if ((p1 = p->uni_pgdir[ucs >> 11]) && (p2 = p1[(ucs >> 6) & 0x1f]) && (h = p2[ucs & 0x3f]) < MAX_GLYPH)