xref: /linux/drivers/tty/vt/consolemap.c (revision d9ebb906a45adc71a62aceb1e3608c847cafa660)
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   {
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   {
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   {
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   {
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 int 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 /**
194  * struct uni_pagedict -- unicode directory
195  *
196  * @uni_pgdir: 32*32*64 table with glyphs
197  * @refcount: reference count of this structure
198  * @sum: checksum
199  * @inverse_translations: best-effort inverse mapping
200  * @inverse_trans_unicode: best-effort inverse mapping to unicode
201  */
202 struct uni_pagedict {
203 	u16		**uni_pgdir[UNI_DIRS];
204 	unsigned long	refcount;
205 	unsigned long	sum;
206 	unsigned char	*inverse_translations[4];
207 	u16		*inverse_trans_unicode;
208 };
209 
210 static struct uni_pagedict *dflt;
211 
212 static void set_inverse_transl(struct vc_data *conp, struct uni_pagedict *p, int i)
213 {
214 	int j, glyph;
215 	unsigned short *t = translations[i];
216 	unsigned char *q;
217 
218 	if (!p) return;
219 	q = p->inverse_translations[i];
220 
221 	if (!q) {
222 		q = p->inverse_translations[i] = kmalloc(MAX_GLYPH, GFP_KERNEL);
223 		if (!q) return;
224 	}
225 	memset(q, 0, MAX_GLYPH);
226 
227 	for (j = 0; j < E_TABSZ; j++) {
228 		glyph = conv_uni_to_pc(conp, t[j]);
229 		if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
230 			/* prefer '-' above SHY etc. */
231 		  	q[glyph] = j;
232 		}
233 	}
234 }
235 
236 static void set_inverse_trans_unicode(struct vc_data *conp,
237 				      struct uni_pagedict *p)
238 {
239 	int i, j, k, glyph;
240 	u16 **p1, *p2;
241 	u16 *q;
242 
243 	if (!p) return;
244 	q = p->inverse_trans_unicode;
245 	if (!q) {
246 		q = p->inverse_trans_unicode =
247 			kmalloc_array(MAX_GLYPH, sizeof(u16), GFP_KERNEL);
248 		if (!q)
249 			return;
250 	}
251 	memset(q, 0, MAX_GLYPH * sizeof(u16));
252 
253 	for (i = 0; i < UNI_DIRS; i++) {
254 		p1 = p->uni_pgdir[i];
255 		if (!p1)
256 			continue;
257 		for (j = 0; j < UNI_DIR_ROWS; j++) {
258 			p2 = p1[j];
259 			if (!p2)
260 				continue;
261 			for (k = 0; k < UNI_ROW_GLYPHS; k++) {
262 				glyph = p2[k];
263 				if (glyph >= 0 && glyph < MAX_GLYPH
264 					       && q[glyph] < 32)
265 		  			q[glyph] = (i << 11) + (j << 6) + k;
266 			}
267 		}
268 	}
269 }
270 
271 unsigned short *set_translate(int m, struct vc_data *vc)
272 {
273 	inv_translate[vc->vc_num] = m;
274 	return translations[m];
275 }
276 
277 /*
278  * Inverse translation is impossible for several reasons:
279  * 1. The font<->character maps are not 1-1.
280  * 2. The text may have been written while a different translation map
281  *    was active.
282  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
283  */
284 u16 inverse_translate(const struct vc_data *conp, u16 glyph, bool use_unicode)
285 {
286 	struct uni_pagedict *p;
287 	int m;
288 
289 	if (glyph >= MAX_GLYPH)
290 		return 0;
291 
292 	p = *conp->vc_uni_pagedir_loc;
293 	if (!p)
294 		return glyph;
295 
296 	if (use_unicode) {
297 		if (!p->inverse_trans_unicode)
298 			return glyph;
299 
300 		return p->inverse_trans_unicode[glyph];
301 	}
302 
303 	m = inv_translate[conp->vc_num];
304 	if (!p->inverse_translations[m])
305 		return glyph;
306 
307 	return p->inverse_translations[m][glyph];
308 }
309 EXPORT_SYMBOL_GPL(inverse_translate);
310 
311 static void update_user_maps(void)
312 {
313 	int i;
314 	struct uni_pagedict *p, *q = NULL;
315 
316 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
317 		if (!vc_cons_allocated(i))
318 			continue;
319 		p = *vc_cons[i].d->vc_uni_pagedir_loc;
320 		if (p && p != q) {
321 			set_inverse_transl(vc_cons[i].d, p, USER_MAP);
322 			set_inverse_trans_unicode(vc_cons[i].d, p);
323 			q = p;
324 		}
325 	}
326 }
327 
328 /*
329  * Load customizable translation table
330  * arg points to a 256 byte translation table.
331  *
332  * The "old" variants are for translation directly to font (using the
333  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
334  * Unicodes explicitly.
335  */
336 int con_set_trans_old(unsigned char __user * arg)
337 {
338 	int i;
339 	unsigned short inbuf[E_TABSZ];
340 	unsigned char ubuf[E_TABSZ];
341 
342 	if (copy_from_user(ubuf, arg, E_TABSZ))
343 		return -EFAULT;
344 
345 	for (i = 0; i < E_TABSZ ; i++)
346 		inbuf[i] = UNI_DIRECT_BASE | ubuf[i];
347 
348 	console_lock();
349 	memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
350 	update_user_maps();
351 	console_unlock();
352 	return 0;
353 }
354 
355 int con_get_trans_old(unsigned char __user * arg)
356 {
357 	int i, ch;
358 	unsigned short *p = translations[USER_MAP];
359 	unsigned char outbuf[E_TABSZ];
360 
361 	console_lock();
362 	for (i = 0; i < E_TABSZ ; i++)
363 	{
364 		ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
365 		outbuf[i] = (ch & ~0xff) ? 0 : ch;
366 	}
367 	console_unlock();
368 
369 	return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
370 }
371 
372 int con_set_trans_new(ushort __user * arg)
373 {
374 	unsigned short inbuf[E_TABSZ];
375 
376 	if (copy_from_user(inbuf, arg, sizeof(inbuf)))
377 		return -EFAULT;
378 
379 	console_lock();
380 	memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
381 	update_user_maps();
382 	console_unlock();
383 	return 0;
384 }
385 
386 int con_get_trans_new(ushort __user * arg)
387 {
388 	unsigned short outbuf[E_TABSZ];
389 
390 	console_lock();
391 	memcpy(outbuf, translations[USER_MAP], sizeof(outbuf));
392 	console_unlock();
393 
394 	return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
395 }
396 
397 /*
398  * Unicode -> current font conversion
399  *
400  * A font has at most 512 chars, usually 256.
401  * But one font position may represent several Unicode chars.
402  * A hashtable is somewhat of a pain to deal with, so use a
403  * "paged table" instead.  Simulation has shown the memory cost of
404  * this 3-level paged table scheme to be comparable to a hash table.
405  */
406 
407 extern u8 dfont_unicount[];	/* Defined in console_defmap.c */
408 extern u16 dfont_unitable[];
409 
410 static void con_release_unimap(struct uni_pagedict *p)
411 {
412 	u16 **p1;
413 	int i, j;
414 
415 	if (p == dflt) dflt = NULL;
416 	for (i = 0; i < UNI_DIRS; i++) {
417 		p1 = p->uni_pgdir[i];
418 		if (p1 != NULL) {
419 			for (j = 0; j < UNI_DIR_ROWS; j++)
420 				kfree(p1[j]);
421 			kfree(p1);
422 		}
423 		p->uni_pgdir[i] = NULL;
424 	}
425 	for (i = 0; i < ARRAY_SIZE(p->inverse_translations); i++) {
426 		kfree(p->inverse_translations[i]);
427 		p->inverse_translations[i] = NULL;
428 	}
429 	kfree(p->inverse_trans_unicode);
430 	p->inverse_trans_unicode = NULL;
431 }
432 
433 /* Caller must hold the console lock */
434 void con_free_unimap(struct vc_data *vc)
435 {
436 	struct uni_pagedict *p;
437 
438 	p = *vc->vc_uni_pagedir_loc;
439 	if (!p)
440 		return;
441 	*vc->vc_uni_pagedir_loc = NULL;
442 	if (--p->refcount)
443 		return;
444 	con_release_unimap(p);
445 	kfree(p);
446 }
447 
448 static int con_unify_unimap(struct vc_data *conp, struct uni_pagedict *p)
449 {
450 	int i, j, k;
451 	struct uni_pagedict *q;
452 
453 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
454 		if (!vc_cons_allocated(i))
455 			continue;
456 		q = *vc_cons[i].d->vc_uni_pagedir_loc;
457 		if (!q || q == p || q->sum != p->sum)
458 			continue;
459 		for (j = 0; j < UNI_DIRS; j++) {
460 			u16 **p1, **q1;
461 			p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
462 			if (!p1 && !q1)
463 				continue;
464 			if (!p1 || !q1)
465 				break;
466 			for (k = 0; k < UNI_DIR_ROWS; k++) {
467 				if (!p1[k] && !q1[k])
468 					continue;
469 				if (!p1[k] || !q1[k])
470 					break;
471 				if (memcmp(p1[k], q1[k],
472 						UNI_ROW_GLYPHS * sizeof(u16)))
473 					break;
474 			}
475 			if (k < UNI_DIR_ROWS)
476 				break;
477 		}
478 		if (j == UNI_DIRS) {
479 			q->refcount++;
480 			*conp->vc_uni_pagedir_loc = q;
481 			con_release_unimap(p);
482 			kfree(p);
483 			return 1;
484 		}
485 	}
486 	return 0;
487 }
488 
489 static int
490 con_insert_unipair(struct uni_pagedict *p, u_short unicode, u_short fontpos)
491 {
492 	int i, n;
493 	u16 **p1, *p2;
494 
495 	p1 = p->uni_pgdir[n = unicode >> 11];
496 	if (!p1) {
497 		p1 = p->uni_pgdir[n] = kmalloc_array(UNI_DIR_ROWS,
498 						     sizeof(u16 *), GFP_KERNEL);
499 		if (!p1) return -ENOMEM;
500 		for (i = 0; i < UNI_DIR_ROWS; i++)
501 			p1[i] = NULL;
502 	}
503 
504 	p2 = p1[n = (unicode >> 6) & 0x1f];
505 	if (!p2) {
506 		p2 = p1[n] = kmalloc_array(UNI_ROW_GLYPHS, sizeof(u16), GFP_KERNEL);
507 		if (!p2) return -ENOMEM;
508 		/* No glyphs for the characters (yet) */
509 		memset(p2, 0xff, UNI_ROW_GLYPHS * sizeof(u16));
510 	}
511 
512 	p2[unicode & 0x3f] = fontpos;
513 
514 	p->sum += (fontpos << 20U) + unicode;
515 
516 	return 0;
517 }
518 
519 /* Caller must hold the lock */
520 static int con_do_clear_unimap(struct vc_data *vc)
521 {
522 	struct uni_pagedict *p, *q;
523 
524 	p = *vc->vc_uni_pagedir_loc;
525 	if (!p || --p->refcount) {
526 		q = kzalloc(sizeof(*p), GFP_KERNEL);
527 		if (!q) {
528 			if (p)
529 				p->refcount++;
530 			return -ENOMEM;
531 		}
532 		q->refcount=1;
533 		*vc->vc_uni_pagedir_loc = q;
534 	} else {
535 		if (p == dflt) dflt = NULL;
536 		p->refcount++;
537 		p->sum = 0;
538 		con_release_unimap(p);
539 	}
540 	return 0;
541 }
542 
543 int con_clear_unimap(struct vc_data *vc)
544 {
545 	int ret;
546 	console_lock();
547 	ret = con_do_clear_unimap(vc);
548 	console_unlock();
549 	return ret;
550 }
551 
552 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
553 {
554 	int err = 0, err1, i;
555 	struct uni_pagedict *p, *q;
556 	struct unipair *unilist, *plist;
557 
558 	if (!ct)
559 		return 0;
560 
561 	unilist = vmemdup_user(list, array_size(sizeof(struct unipair), ct));
562 	if (IS_ERR(unilist))
563 		return PTR_ERR(unilist);
564 
565 	console_lock();
566 
567 	/* Save original vc_unipagdir_loc in case we allocate a new one */
568 	p = *vc->vc_uni_pagedir_loc;
569 
570 	if (!p) {
571 		err = -EINVAL;
572 
573 		goto out_unlock;
574 	}
575 
576 	if (p->refcount > 1) {
577 		int j, k;
578 		u16 **p1, *p2, l;
579 
580 		err1 = con_do_clear_unimap(vc);
581 		if (err1) {
582 			err = err1;
583 			goto out_unlock;
584 		}
585 
586 		/*
587 		 * Since refcount was > 1, con_clear_unimap() allocated a
588 		 * a new uni_pagedict for this vc.  Re: p != q
589 		 */
590 		q = *vc->vc_uni_pagedir_loc;
591 
592 		/*
593 		 * uni_pgdir is a 32*32*64 table with rows allocated
594 		 * when its first entry is added.  The unicode value must
595 		 * still be incremented for empty rows.  We are copying
596 		 * entries from "p" (old) to "q" (new).
597 		 */
598 		l = 0;		/* unicode value */
599 		for (i = 0; i < UNI_DIRS; i++) {
600 		p1 = p->uni_pgdir[i];
601 		if (p1)
602 			for (j = 0; j < UNI_DIR_ROWS; j++) {
603 			p2 = p1[j];
604 			if (p2) {
605 				for (k = 0; k < UNI_ROW_GLYPHS; k++, l++)
606 				if (p2[k] != 0xffff) {
607 					/*
608 					 * Found one, copy entry for unicode
609 					 * l with fontpos value p2[k].
610 					 */
611 					err1 = con_insert_unipair(q, l, p2[k]);
612 					if (err1) {
613 						p->refcount++;
614 						*vc->vc_uni_pagedir_loc = p;
615 						con_release_unimap(q);
616 						kfree(q);
617 						err = err1;
618 						goto out_unlock;
619 					}
620 				}
621 			} else {
622 				/* Account for row of 64 empty entries */
623 				l += UNI_ROW_GLYPHS;
624 			}
625 		}
626 		else
627 			/* Account for empty table */
628 			l += UNI_DIR_ROWS * UNI_ROW_GLYPHS;
629 		}
630 
631 		/*
632 		 * Finished copying font table, set vc_uni_pagedir to new table
633 		 */
634 		p = q;
635 	} else if (p == dflt) {
636 		dflt = NULL;
637 	}
638 
639 	/*
640 	 * Insert user specified unicode pairs into new table.
641 	 */
642 	for (plist = unilist; ct; ct--, plist++) {
643 		err1 = con_insert_unipair(p, plist->unicode, plist->fontpos);
644 		if (err1)
645 			err = err1;
646 	}
647 
648 	/*
649 	 * Merge with fontmaps of any other virtual consoles.
650 	 */
651 	if (con_unify_unimap(vc, p))
652 		goto out_unlock;
653 
654 	for (i = 0; i <= 3; i++)
655 		set_inverse_transl(vc, p, i); /* Update inverse translations */
656 	set_inverse_trans_unicode(vc, p);
657 
658 out_unlock:
659 	console_unlock();
660 	kvfree(unilist);
661 	return err;
662 }
663 
664 /**
665  *	con_set_default_unimap	-	set default unicode map
666  *	@vc: the console we are updating
667  *
668  *	Loads the unimap for the hardware font, as defined in uni_hash.tbl.
669  *	The representation used was the most compact I could come up
670  *	with.  This routine is executed at video setup, and when the
671  *	PIO_FONTRESET ioctl is called.
672  *
673  *	The caller must hold the console lock
674  */
675 int con_set_default_unimap(struct vc_data *vc)
676 {
677 	int i, j, err = 0, err1;
678 	u16 *q;
679 	struct uni_pagedict *p;
680 
681 	if (dflt) {
682 		p = *vc->vc_uni_pagedir_loc;
683 		if (p == dflt)
684 			return 0;
685 
686 		dflt->refcount++;
687 		*vc->vc_uni_pagedir_loc = dflt;
688 		if (p && !--p->refcount) {
689 			con_release_unimap(p);
690 			kfree(p);
691 		}
692 		return 0;
693 	}
694 
695 	/* The default font is always 256 characters */
696 
697 	err = con_do_clear_unimap(vc);
698 	if (err)
699 		return err;
700 
701 	p = *vc->vc_uni_pagedir_loc;
702 	q = dfont_unitable;
703 
704 	for (i = 0; i < 256; i++)
705 		for (j = dfont_unicount[i]; j; j--) {
706 			err1 = con_insert_unipair(p, *(q++), i);
707 			if (err1)
708 				err = err1;
709 		}
710 
711 	if (con_unify_unimap(vc, p)) {
712 		dflt = *vc->vc_uni_pagedir_loc;
713 		return err;
714 	}
715 
716 	for (i = 0; i <= 3; i++)
717 		set_inverse_transl(vc, p, i);	/* Update all inverse translations */
718 	set_inverse_trans_unicode(vc, p);
719 	dflt = p;
720 	return err;
721 }
722 EXPORT_SYMBOL(con_set_default_unimap);
723 
724 /**
725  *	con_copy_unimap		-	copy unimap between two vts
726  *	@dst_vc: target
727  *	@src_vc: source
728  *
729  *	The caller must hold the console lock when invoking this method
730  */
731 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
732 {
733 	struct uni_pagedict *q;
734 
735 	if (!*src_vc->vc_uni_pagedir_loc)
736 		return -EINVAL;
737 	if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
738 		return 0;
739 	con_free_unimap(dst_vc);
740 	q = *src_vc->vc_uni_pagedir_loc;
741 	q->refcount++;
742 	*dst_vc->vc_uni_pagedir_loc = q;
743 	return 0;
744 }
745 EXPORT_SYMBOL(con_copy_unimap);
746 
747 /*
748  *	con_get_unimap		-	get the unicode map
749  *
750  *	Read the console unicode data for this console. Called from the ioctl
751  *	handlers.
752  */
753 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
754 {
755 	int i, j, k, ret = 0;
756 	ushort ect;
757 	u16 **p1, *p2;
758 	struct uni_pagedict *p;
759 	struct unipair *unilist;
760 
761 	unilist = kvmalloc_array(ct, sizeof(struct unipair), GFP_KERNEL);
762 	if (!unilist)
763 		return -ENOMEM;
764 
765 	console_lock();
766 
767 	ect = 0;
768 	if (*vc->vc_uni_pagedir_loc) {
769 		p = *vc->vc_uni_pagedir_loc;
770 		for (i = 0; i < UNI_DIRS; i++) {
771 		p1 = p->uni_pgdir[i];
772 		if (p1)
773 			for (j = 0; j < UNI_DIR_ROWS; j++) {
774 			p2 = *(p1++);
775 			if (p2)
776 				for (k = 0; k < UNI_ROW_GLYPHS; k++, p2++) {
777 					if (*p2 >= MAX_GLYPH)
778 						continue;
779 					if (ect < ct) {
780 						unilist[ect].unicode =
781 							(i<<11)+(j<<6)+k;
782 						unilist[ect].fontpos = *p2;
783 					}
784 					ect++;
785 				}
786 			}
787 		}
788 	}
789 	console_unlock();
790 	if (copy_to_user(list, unilist, min(ect, ct) * sizeof(struct unipair)))
791 		ret = -EFAULT;
792 	put_user(ect, uct);
793 	kvfree(unilist);
794 	return ret ? ret : (ect <= ct) ? 0 : -ENOMEM;
795 }
796 
797 /*
798  * Always use USER_MAP. These functions are used by the keyboard,
799  * which shouldn't be affected by G0/G1 switching, etc.
800  * If the user map still contains default values, i.e. the
801  * direct-to-font mapping, then assume user is using Latin1.
802  *
803  * FIXME: at some point we need to decide if we want to lock the table
804  * update element itself via the keyboard_event_lock for consistency with the
805  * keyboard driver as well as the consoles
806  */
807 /* may be called during an interrupt */
808 u32 conv_8bit_to_uni(unsigned char c)
809 {
810 	unsigned short uni = translations[USER_MAP][c];
811 	return uni == (0xf000 | c) ? c : uni;
812 }
813 
814 int conv_uni_to_8bit(u32 uni)
815 {
816 	int c;
817 	for (c = 0; c < ARRAY_SIZE(translations[USER_MAP]); c++)
818 		if (translations[USER_MAP][c] == uni ||
819 		   (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
820 			return c;
821 	return -1;
822 }
823 
824 int
825 conv_uni_to_pc(struct vc_data *conp, long ucs)
826 {
827 	int h;
828 	u16 **p1, *p2;
829 	struct uni_pagedict *p;
830 
831 	/* Only 16-bit codes supported at this time */
832 	if (ucs > 0xffff)
833 		return -4;		/* Not found */
834 	else if (ucs < 0x20)
835 		return -1;		/* Not a printable character */
836 	else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
837 		return -2;			/* Zero-width space */
838 	/*
839 	 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
840 	 * which always has a 1:1 mapping to the currently loaded font.  The
841 	 * UNI_DIRECT_MASK indicates the bit span of the region.
842 	 */
843 	else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
844 		return ucs & UNI_DIRECT_MASK;
845 
846 	if (!*conp->vc_uni_pagedir_loc)
847 		return -3;
848 
849 	p = *conp->vc_uni_pagedir_loc;
850 	if ((p1 = p->uni_pgdir[ucs >> 11]) &&
851 	    (p2 = p1[(ucs >> 6) & 0x1f]) &&
852 	    (h = p2[ucs & 0x3f]) < MAX_GLYPH)
853 		return h;
854 
855 	return -4;		/* not found */
856 }
857 
858 /*
859  * This is called at sys_setup time, after memory and the console are
860  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
861  * from this function, hence the call from sys_setup.
862  */
863 void __init
864 console_map_init(void)
865 {
866 	int i;
867 
868 	for (i = 0; i < MAX_NR_CONSOLES; i++)
869 		if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
870 			con_set_default_unimap(vc_cons[i].d);
871 }
872 
873