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