xref: /openbmc/linux/drivers/tty/vt/consolemap.c (revision 5a904a936b407624cd1ff5ee3f1675ca3d2366a5)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * consolemap.c
4  *
5  * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
6  * to font positions.
7  *
8  * aeb, 950210
9  *
10  * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
11  *
12  * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
13  *
14  * In order to prevent the following circular lock dependency:
15  *   &mm->mmap_lock --> cpu_hotplug.lock --> console_lock --> &mm->mmap_lock
16  *
17  * We cannot allow page fault to happen while holding the console_lock.
18  * Therefore, all the userspace copy operations have to be done outside
19  * the console_lock critical sections.
20  *
21  * As all the affected functions are all called directly from vt_ioctl(), we
22  * can allocate some small buffers directly on stack without worrying about
23  * stack overflow.
24  */
25 
26 #include <linux/module.h>
27 #include <linux/kd.h>
28 #include <linux/errno.h>
29 #include <linux/mm.h>
30 #include <linux/slab.h>
31 #include <linux/init.h>
32 #include <linux/tty.h>
33 #include <linux/uaccess.h>
34 #include <linux/console.h>
35 #include <linux/consolemap.h>
36 #include <linux/vt_kern.h>
37 #include <linux/string.h>
38 
39 static unsigned short translations[][256] = {
40   /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
41   [LAT1_MAP] = {
42     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
43     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
44     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
45     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
46     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
47     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
48     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
49     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
50     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
51     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
52     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
53     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
54     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
55     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
56     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
57     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
58     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
59     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
60     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
61     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
62     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
63     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
64     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
65     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
66     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
67     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
68     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
69     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
70     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
71     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
72     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
73     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
74   },
75   /* VT100 graphics mapped to Unicode */
76   [GRAF_MAP] = {
77     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
78     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
79     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
80     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
81     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
82     0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
83     0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
84     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
85     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
86     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
87     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
88     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
89     0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
90     0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
91     0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
92     0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
93     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
94     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
95     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
96     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
97     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
98     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
99     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
100     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
101     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
102     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
103     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
104     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
105     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
106     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
107     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
108     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
109   },
110   /* IBM Codepage 437 mapped to Unicode */
111   [IBMPC_MAP] = {
112     0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
113     0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
114     0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
115     0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
116     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
117     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
118     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
119     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
120     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
121     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
122     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
123     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
124     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
125     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
126     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
127     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
128     0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
129     0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
130     0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
131     0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
132     0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
133     0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
134     0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
135     0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
136     0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
137     0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
138     0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
139     0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
140     0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
141     0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
142     0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
143     0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
144   },
145   /* User mapping -- default to codes for direct font mapping */
146   [USER_MAP] = {
147     0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
148     0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
149     0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
150     0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
151     0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
152     0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
153     0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
154     0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
155     0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
156     0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
157     0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
158     0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
159     0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
160     0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
161     0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
162     0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
163     0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
164     0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
165     0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
166     0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
167     0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
168     0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
169     0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
170     0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
171     0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
172     0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
173     0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
174     0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
175     0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
176     0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
177     0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
178     0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
179   }
180 };
181 
182 /* The standard kernel character-to-font mappings are not invertible
183    -- this is just a best effort. */
184 
185 #define MAX_GLYPH 512		/* Max possible glyph value */
186 
187 static enum translation_map inv_translate[MAX_NR_CONSOLES];
188 
189 #define UNI_DIRS	32U
190 #define UNI_DIR_ROWS	32U
191 #define UNI_ROW_GLYPHS	64U
192 
193 #define UNI_DIR(uni)		( (uni)                   >> 11)
194 #define UNI_ROW(uni)		(((uni) & GENMASK(10, 6)) >>  6)
195 #define UNI_GLYPH(uni)		( (uni) & GENMASK( 5, 0))
196 #define UNI(dir, row, glyph)	(((dir) << 11) | ((row) << 6) | (glyph))
197 
198 /**
199  * struct uni_pagedict -- unicode directory
200  *
201  * @uni_pgdir: 32*32*64 table with glyphs
202  * @refcount: reference count of this structure
203  * @sum: checksum
204  * @inverse_translations: best-effort inverse mapping
205  * @inverse_trans_unicode: best-effort inverse mapping to unicode
206  */
207 struct uni_pagedict {
208 	u16		**uni_pgdir[UNI_DIRS];
209 	unsigned long	refcount;
210 	unsigned long	sum;
211 	unsigned char	*inverse_translations[LAST_MAP + 1];
212 	u16		*inverse_trans_unicode;
213 };
214 
215 static struct uni_pagedict *dflt;
216 
217 static void set_inverse_transl(struct vc_data *conp, struct uni_pagedict *p,
218 	       enum translation_map m)
219 {
220 	int j, glyph;
221 	unsigned short *t = translations[m];
222 	unsigned char *q;
223 
224 	if (!p)
225 		return;
226 	q = p->inverse_translations[m];
227 
228 	if (!q) {
229 		q = p->inverse_translations[m] = kmalloc(MAX_GLYPH, GFP_KERNEL);
230 		if (!q)
231 			return;
232 	}
233 	memset(q, 0, MAX_GLYPH);
234 
235 	for (j = 0; j < E_TABSZ; j++) {
236 		glyph = conv_uni_to_pc(conp, t[j]);
237 		if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
238 			/* prefer '-' above SHY etc. */
239 		  	q[glyph] = j;
240 		}
241 	}
242 }
243 
244 static void set_inverse_trans_unicode(struct vc_data *conp,
245 				      struct uni_pagedict *p)
246 {
247 	int i, j, k, glyph;
248 	u16 **p1, *p2;
249 	u16 *q;
250 
251 	if (!p)
252 		return;
253 	q = p->inverse_trans_unicode;
254 	if (!q) {
255 		q = p->inverse_trans_unicode = kmalloc_array(MAX_GLYPH,
256 				sizeof(*q), GFP_KERNEL);
257 		if (!q)
258 			return;
259 	}
260 	memset(q, 0, MAX_GLYPH * sizeof(*q));
261 
262 	for (i = 0; i < UNI_DIRS; i++) {
263 		p1 = p->uni_pgdir[i];
264 		if (!p1)
265 			continue;
266 		for (j = 0; j < UNI_DIR_ROWS; j++) {
267 			p2 = p1[j];
268 			if (!p2)
269 				continue;
270 			for (k = 0; k < UNI_ROW_GLYPHS; k++) {
271 				glyph = p2[k];
272 				if (glyph >= 0 && glyph < MAX_GLYPH
273 					       && q[glyph] < 32)
274 					q[glyph] = UNI(i, j, k);
275 			}
276 		}
277 	}
278 }
279 
280 unsigned short *set_translate(enum translation_map m, struct vc_data *vc)
281 {
282 	inv_translate[vc->vc_num] = m;
283 	return translations[m];
284 }
285 
286 /*
287  * Inverse translation is impossible for several reasons:
288  * 1. The font<->character maps are not 1-1.
289  * 2. The text may have been written while a different translation map
290  *    was active.
291  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
292  */
293 u16 inverse_translate(const struct vc_data *conp, u16 glyph, bool use_unicode)
294 {
295 	struct uni_pagedict *p;
296 	enum translation_map m;
297 
298 	if (glyph >= MAX_GLYPH)
299 		return 0;
300 
301 	p = *conp->vc_uni_pagedir_loc;
302 	if (!p)
303 		return glyph;
304 
305 	if (use_unicode) {
306 		if (!p->inverse_trans_unicode)
307 			return glyph;
308 
309 		return p->inverse_trans_unicode[glyph];
310 	}
311 
312 	m = inv_translate[conp->vc_num];
313 	if (!p->inverse_translations[m])
314 		return glyph;
315 
316 	return p->inverse_translations[m][glyph];
317 }
318 EXPORT_SYMBOL_GPL(inverse_translate);
319 
320 static void update_user_maps(void)
321 {
322 	int i;
323 	struct uni_pagedict *p, *q = NULL;
324 
325 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
326 		if (!vc_cons_allocated(i))
327 			continue;
328 		p = *vc_cons[i].d->vc_uni_pagedir_loc;
329 		if (p && p != q) {
330 			set_inverse_transl(vc_cons[i].d, p, USER_MAP);
331 			set_inverse_trans_unicode(vc_cons[i].d, p);
332 			q = p;
333 		}
334 	}
335 }
336 
337 /*
338  * Load customizable translation table
339  * arg points to a 256 byte translation table.
340  *
341  * The "old" variants are for translation directly to font (using the
342  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
343  * Unicodes explicitly.
344  */
345 int con_set_trans_old(unsigned char __user * arg)
346 {
347 	int i;
348 	unsigned short inbuf[E_TABSZ];
349 	unsigned char ubuf[E_TABSZ];
350 
351 	if (copy_from_user(ubuf, arg, E_TABSZ))
352 		return -EFAULT;
353 
354 	for (i = 0; i < E_TABSZ ; i++)
355 		inbuf[i] = UNI_DIRECT_BASE | ubuf[i];
356 
357 	console_lock();
358 	memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
359 	update_user_maps();
360 	console_unlock();
361 	return 0;
362 }
363 
364 int con_get_trans_old(unsigned char __user * arg)
365 {
366 	int i, ch;
367 	unsigned short *p = translations[USER_MAP];
368 	unsigned char outbuf[E_TABSZ];
369 
370 	console_lock();
371 	for (i = 0; i < E_TABSZ ; i++)
372 	{
373 		ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
374 		outbuf[i] = (ch & ~0xff) ? 0 : ch;
375 	}
376 	console_unlock();
377 
378 	return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
379 }
380 
381 int con_set_trans_new(ushort __user * arg)
382 {
383 	unsigned short inbuf[E_TABSZ];
384 
385 	if (copy_from_user(inbuf, arg, sizeof(inbuf)))
386 		return -EFAULT;
387 
388 	console_lock();
389 	memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
390 	update_user_maps();
391 	console_unlock();
392 	return 0;
393 }
394 
395 int con_get_trans_new(ushort __user * arg)
396 {
397 	unsigned short outbuf[E_TABSZ];
398 
399 	console_lock();
400 	memcpy(outbuf, translations[USER_MAP], sizeof(outbuf));
401 	console_unlock();
402 
403 	return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
404 }
405 
406 /*
407  * Unicode -> current font conversion
408  *
409  * A font has at most 512 chars, usually 256.
410  * But one font position may represent several Unicode chars.
411  * A hashtable is somewhat of a pain to deal with, so use a
412  * "paged table" instead.  Simulation has shown the memory cost of
413  * this 3-level paged table scheme to be comparable to a hash table.
414  */
415 
416 extern u8 dfont_unicount[];	/* Defined in console_defmap.c */
417 extern u16 dfont_unitable[];
418 
419 static void con_release_unimap(struct uni_pagedict *p)
420 {
421 	u16 **p1;
422 	int i, j;
423 
424 	if (p == dflt)
425 		dflt = NULL;
426 	for (i = 0; i < UNI_DIRS; i++) {
427 		p1 = p->uni_pgdir[i];
428 		if (p1 != NULL) {
429 			for (j = 0; j < UNI_DIR_ROWS; j++)
430 				kfree(p1[j]);
431 			kfree(p1);
432 		}
433 		p->uni_pgdir[i] = NULL;
434 	}
435 	for (i = 0; i < ARRAY_SIZE(p->inverse_translations); i++) {
436 		kfree(p->inverse_translations[i]);
437 		p->inverse_translations[i] = NULL;
438 	}
439 	kfree(p->inverse_trans_unicode);
440 	p->inverse_trans_unicode = NULL;
441 }
442 
443 /* Caller must hold the console lock */
444 void con_free_unimap(struct vc_data *vc)
445 {
446 	struct uni_pagedict *p;
447 
448 	p = *vc->vc_uni_pagedir_loc;
449 	if (!p)
450 		return;
451 	*vc->vc_uni_pagedir_loc = NULL;
452 	if (--p->refcount)
453 		return;
454 	con_release_unimap(p);
455 	kfree(p);
456 }
457 
458 static int con_unify_unimap(struct vc_data *conp, struct uni_pagedict *p)
459 {
460 	int i, j, k;
461 	struct uni_pagedict *q;
462 
463 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
464 		if (!vc_cons_allocated(i))
465 			continue;
466 		q = *vc_cons[i].d->vc_uni_pagedir_loc;
467 		if (!q || q == p || q->sum != p->sum)
468 			continue;
469 		for (j = 0; j < UNI_DIRS; j++) {
470 			u16 **p1, **q1;
471 			p1 = p->uni_pgdir[j];
472 			q1 = q->uni_pgdir[j];
473 			if (!p1 && !q1)
474 				continue;
475 			if (!p1 || !q1)
476 				break;
477 			for (k = 0; k < UNI_DIR_ROWS; k++) {
478 				if (!p1[k] && !q1[k])
479 					continue;
480 				if (!p1[k] || !q1[k])
481 					break;
482 				if (memcmp(p1[k], q1[k], UNI_ROW_GLYPHS *
483 							sizeof(*p1[k])))
484 					break;
485 			}
486 			if (k < UNI_DIR_ROWS)
487 				break;
488 		}
489 		if (j == UNI_DIRS) {
490 			q->refcount++;
491 			*conp->vc_uni_pagedir_loc = q;
492 			con_release_unimap(p);
493 			kfree(p);
494 			return 1;
495 		}
496 	}
497 	return 0;
498 }
499 
500 static int
501 con_insert_unipair(struct uni_pagedict *p, u_short unicode, u_short fontpos)
502 {
503 	int n;
504 	u16 **p1, *p2;
505 
506 	n = UNI_DIR(unicode);
507 	p1 = p->uni_pgdir[n];
508 	if (!p1) {
509 		p1 = p->uni_pgdir[n] = kcalloc(UNI_DIR_ROWS, sizeof(*p1),
510 				GFP_KERNEL);
511 		if (!p1)
512 			return -ENOMEM;
513 	}
514 
515 	n = UNI_ROW(unicode);
516 	p2 = p1[n];
517 	if (!p2) {
518 		p2 = p1[n] = kmalloc_array(UNI_ROW_GLYPHS, sizeof(*p2),
519 				GFP_KERNEL);
520 		if (!p2)
521 			return -ENOMEM;
522 		/* No glyphs for the characters (yet) */
523 		memset(p2, 0xff, UNI_ROW_GLYPHS * sizeof(*p2));
524 	}
525 
526 	p2[UNI_GLYPH(unicode)] = fontpos;
527 
528 	p->sum += (fontpos << 20U) + unicode;
529 
530 	return 0;
531 }
532 
533 /* Caller must hold the lock */
534 static int con_do_clear_unimap(struct vc_data *vc)
535 {
536 	struct uni_pagedict *p, *q;
537 
538 	p = *vc->vc_uni_pagedir_loc;
539 	if (!p || --p->refcount) {
540 		q = kzalloc(sizeof(*p), GFP_KERNEL);
541 		if (!q) {
542 			if (p)
543 				p->refcount++;
544 			return -ENOMEM;
545 		}
546 		q->refcount=1;
547 		*vc->vc_uni_pagedir_loc = q;
548 	} else {
549 		if (p == dflt)
550 			dflt = NULL;
551 		p->refcount++;
552 		p->sum = 0;
553 		con_release_unimap(p);
554 	}
555 	return 0;
556 }
557 
558 int con_clear_unimap(struct vc_data *vc)
559 {
560 	int ret;
561 	console_lock();
562 	ret = con_do_clear_unimap(vc);
563 	console_unlock();
564 	return ret;
565 }
566 
567 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
568 {
569 	int err = 0, err1, i;
570 	struct uni_pagedict *p, *q;
571 	struct unipair *unilist, *plist;
572 
573 	if (!ct)
574 		return 0;
575 
576 	unilist = vmemdup_user(list, array_size(sizeof(*unilist), ct));
577 	if (IS_ERR(unilist))
578 		return PTR_ERR(unilist);
579 
580 	console_lock();
581 
582 	/* Save original vc_unipagdir_loc in case we allocate a new one */
583 	p = *vc->vc_uni_pagedir_loc;
584 	if (!p) {
585 		err = -EINVAL;
586 		goto out_unlock;
587 	}
588 
589 	if (p->refcount > 1) {
590 		int j, k;
591 		u16 **p1, *p2, l;
592 
593 		err1 = con_do_clear_unimap(vc);
594 		if (err1) {
595 			err = err1;
596 			goto out_unlock;
597 		}
598 
599 		/*
600 		 * Since refcount was > 1, con_clear_unimap() allocated a
601 		 * a new uni_pagedict for this vc.  Re: p != q
602 		 */
603 		q = *vc->vc_uni_pagedir_loc;
604 
605 		/*
606 		 * uni_pgdir is a 32*32*64 table with rows allocated
607 		 * when its first entry is added.  The unicode value must
608 		 * still be incremented for empty rows.  We are copying
609 		 * entries from "p" (old) to "q" (new).
610 		 */
611 		l = 0;		/* unicode value */
612 		for (i = 0; i < UNI_DIRS; i++) {
613 			p1 = p->uni_pgdir[i];
614 			if (!p1) {
615 				/* Account for empty table */
616 				l += UNI_DIR_ROWS * UNI_ROW_GLYPHS;
617 				continue;
618 			}
619 
620 			for (j = 0; j < UNI_DIR_ROWS; j++) {
621 				p2 = p1[j];
622 				if (!p2) {
623 					/*
624 					 * Account for row of 64 empty entries
625 					 */
626 					l += UNI_ROW_GLYPHS;
627 					continue;
628 				}
629 
630 				for (k = 0; k < UNI_ROW_GLYPHS; k++, l++) {
631 					if (p2[k] == 0xffff)
632 						continue;
633 					/*
634 					 * Found one, copy entry for unicode
635 					 * l with fontpos value p2[k].
636 					 */
637 					err1 = con_insert_unipair(q, l, p2[k]);
638 					if (err1) {
639 						p->refcount++;
640 						*vc->vc_uni_pagedir_loc = p;
641 						con_release_unimap(q);
642 						kfree(q);
643 						err = err1;
644 						goto out_unlock;
645 					}
646 				}
647 			}
648 		}
649 
650 		/*
651 		 * Finished copying font table, set vc_uni_pagedir to new table
652 		 */
653 		p = q;
654 	} else if (p == dflt) {
655 		dflt = NULL;
656 	}
657 
658 	/*
659 	 * Insert user specified unicode pairs into new table.
660 	 */
661 	for (plist = unilist; ct; ct--, plist++) {
662 		err1 = con_insert_unipair(p, plist->unicode, plist->fontpos);
663 		if (err1)
664 			err = err1;
665 	}
666 
667 	/*
668 	 * Merge with fontmaps of any other virtual consoles.
669 	 */
670 	if (con_unify_unimap(vc, p))
671 		goto out_unlock;
672 
673 	for (enum translation_map m = FIRST_MAP; m <= LAST_MAP; m++)
674 		set_inverse_transl(vc, p, m); /* Update inverse translations */
675 	set_inverse_trans_unicode(vc, p);
676 
677 out_unlock:
678 	console_unlock();
679 	kvfree(unilist);
680 	return err;
681 }
682 
683 /**
684  *	con_set_default_unimap	-	set default unicode map
685  *	@vc: the console we are updating
686  *
687  *	Loads the unimap for the hardware font, as defined in uni_hash.tbl.
688  *	The representation used was the most compact I could come up
689  *	with.  This routine is executed at video setup, and when the
690  *	PIO_FONTRESET ioctl is called.
691  *
692  *	The caller must hold the console lock
693  */
694 int con_set_default_unimap(struct vc_data *vc)
695 {
696 	int i, j, err = 0, err1;
697 	u16 *q;
698 	struct uni_pagedict *p;
699 
700 	if (dflt) {
701 		p = *vc->vc_uni_pagedir_loc;
702 		if (p == dflt)
703 			return 0;
704 
705 		dflt->refcount++;
706 		*vc->vc_uni_pagedir_loc = dflt;
707 		if (p && !--p->refcount) {
708 			con_release_unimap(p);
709 			kfree(p);
710 		}
711 		return 0;
712 	}
713 
714 	/* The default font is always 256 characters */
715 
716 	err = con_do_clear_unimap(vc);
717 	if (err)
718 		return err;
719 
720 	p = *vc->vc_uni_pagedir_loc;
721 	q = dfont_unitable;
722 
723 	for (i = 0; i < 256; i++)
724 		for (j = dfont_unicount[i]; j; j--) {
725 			err1 = con_insert_unipair(p, *(q++), i);
726 			if (err1)
727 				err = err1;
728 		}
729 
730 	if (con_unify_unimap(vc, p)) {
731 		dflt = *vc->vc_uni_pagedir_loc;
732 		return err;
733 	}
734 
735 	for (enum translation_map m = FIRST_MAP; m <= LAST_MAP; m++)
736 		set_inverse_transl(vc, p, m);	/* Update all inverse translations */
737 	set_inverse_trans_unicode(vc, p);
738 	dflt = p;
739 	return err;
740 }
741 EXPORT_SYMBOL(con_set_default_unimap);
742 
743 /**
744  *	con_copy_unimap		-	copy unimap between two vts
745  *	@dst_vc: target
746  *	@src_vc: source
747  *
748  *	The caller must hold the console lock when invoking this method
749  */
750 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
751 {
752 	struct uni_pagedict *q;
753 
754 	if (!*src_vc->vc_uni_pagedir_loc)
755 		return -EINVAL;
756 	if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
757 		return 0;
758 	con_free_unimap(dst_vc);
759 	q = *src_vc->vc_uni_pagedir_loc;
760 	q->refcount++;
761 	*dst_vc->vc_uni_pagedir_loc = q;
762 	return 0;
763 }
764 EXPORT_SYMBOL(con_copy_unimap);
765 
766 /*
767  *	con_get_unimap		-	get the unicode map
768  *
769  *	Read the console unicode data for this console. Called from the ioctl
770  *	handlers.
771  */
772 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct,
773 		struct unipair __user *list)
774 {
775 	int i, j, k, ret = 0;
776 	ushort ect;
777 	u16 **p1, *p2;
778 	struct uni_pagedict *p;
779 	struct unipair *unilist;
780 
781 	unilist = kvmalloc_array(ct, sizeof(*unilist), GFP_KERNEL);
782 	if (!unilist)
783 		return -ENOMEM;
784 
785 	console_lock();
786 
787 	ect = 0;
788 	p = *vc->vc_uni_pagedir_loc;
789 	if (!p)
790 		goto unlock;
791 
792 	for (i = 0; i < UNI_DIRS; i++) {
793 		p1 = p->uni_pgdir[i];
794 		if (!p1)
795 			continue;
796 
797 		for (j = 0; j < UNI_DIR_ROWS; j++, p1++) {
798 			p2 = *p1;
799 			if (!p2)
800 				continue;
801 
802 			for (k = 0; k < UNI_ROW_GLYPHS; k++, p2++) {
803 				if (*p2 >= MAX_GLYPH)
804 					continue;
805 				if (ect < ct) {
806 					unilist[ect].unicode = UNI(i, j, k);
807 					unilist[ect].fontpos = *p2;
808 				}
809 				ect++;
810 			}
811 		}
812 	}
813 unlock:
814 	console_unlock();
815 	if (copy_to_user(list, unilist, min(ect, ct) * sizeof(*unilist)))
816 		ret = -EFAULT;
817 	if (put_user(ect, uct))
818 		ret = -EFAULT;
819 	kvfree(unilist);
820 	return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
821 }
822 
823 /*
824  * Always use USER_MAP. These functions are used by the keyboard,
825  * which shouldn't be affected by G0/G1 switching, etc.
826  * If the user map still contains default values, i.e. the
827  * direct-to-font mapping, then assume user is using Latin1.
828  *
829  * FIXME: at some point we need to decide if we want to lock the table
830  * update element itself via the keyboard_event_lock for consistency with the
831  * keyboard driver as well as the consoles
832  */
833 /* may be called during an interrupt */
834 u32 conv_8bit_to_uni(unsigned char c)
835 {
836 	unsigned short uni = translations[USER_MAP][c];
837 	return uni == (0xf000 | c) ? c : uni;
838 }
839 
840 int conv_uni_to_8bit(u32 uni)
841 {
842 	int c;
843 	for (c = 0; c < ARRAY_SIZE(translations[USER_MAP]); c++)
844 		if (translations[USER_MAP][c] == uni ||
845 		   (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
846 			return c;
847 	return -1;
848 }
849 
850 int
851 conv_uni_to_pc(struct vc_data *conp, long ucs)
852 {
853 	int h;
854 	u16 **p1, *p2;
855 	struct uni_pagedict *p;
856 
857 	/* Only 16-bit codes supported at this time */
858 	if (ucs > 0xffff)
859 		return -4;		/* Not found */
860 	else if (ucs < 0x20)
861 		return -1;		/* Not a printable character */
862 	else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
863 		return -2;			/* Zero-width space */
864 	/*
865 	 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
866 	 * which always has a 1:1 mapping to the currently loaded font.  The
867 	 * UNI_DIRECT_MASK indicates the bit span of the region.
868 	 */
869 	else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
870 		return ucs & UNI_DIRECT_MASK;
871 
872 	if (!*conp->vc_uni_pagedir_loc)
873 		return -3;
874 
875 	p = *conp->vc_uni_pagedir_loc;
876 	if ((p1 = p->uni_pgdir[UNI_DIR(ucs)]) &&
877 	    (p2 = p1[UNI_ROW(ucs)]) &&
878 	    (h = p2[UNI_GLYPH(ucs)]) < MAX_GLYPH)
879 		return h;
880 
881 	return -4;		/* not found */
882 }
883 
884 /*
885  * This is called at sys_setup time, after memory and the console are
886  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
887  * from this function, hence the call from sys_setup.
888  */
889 void __init
890 console_map_init(void)
891 {
892 	int i;
893 
894 	for (i = 0; i < MAX_NR_CONSOLES; i++)
895 		if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
896 			con_set_default_unimap(vc_cons[i].d);
897 }
898 
899