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