hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/x86/lib/insn.c
....@@ -1,19 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * x86 instruction analysis
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
174 *
185 * Copyright (C) IBM Corporation, 2002, 2004, 2009
196 */
....@@ -23,8 +10,13 @@
2310 #else
2411 #include <string.h>
2512 #endif
26
-#include <asm/inat.h>
27
-#include <asm/insn.h>
13
+#include <asm/inat.h> /*__ignore_sync_check__ */
14
+#include <asm/insn.h> /* __ignore_sync_check__ */
15
+
16
+#include <linux/errno.h>
17
+#include <linux/kconfig.h>
18
+
19
+#include <asm/emulate_prefix.h> /* __ignore_sync_check__ */
2820
2921 /* Verify next sizeof(t) bytes can be on the same instruction */
3022 #define validate_next(t, insn, n) \
....@@ -71,6 +63,36 @@
7163 insn->addr_bytes = 4;
7264 }
7365
66
+static const insn_byte_t xen_prefix[] = { __XEN_EMULATE_PREFIX };
67
+static const insn_byte_t kvm_prefix[] = { __KVM_EMULATE_PREFIX };
68
+
69
+static int __insn_get_emulate_prefix(struct insn *insn,
70
+ const insn_byte_t *prefix, size_t len)
71
+{
72
+ size_t i;
73
+
74
+ for (i = 0; i < len; i++) {
75
+ if (peek_nbyte_next(insn_byte_t, insn, i) != prefix[i])
76
+ goto err_out;
77
+ }
78
+
79
+ insn->emulate_prefix_size = len;
80
+ insn->next_byte += len;
81
+
82
+ return 1;
83
+
84
+err_out:
85
+ return 0;
86
+}
87
+
88
+static void insn_get_emulate_prefix(struct insn *insn)
89
+{
90
+ if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
91
+ return;
92
+
93
+ __insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
94
+}
95
+
7496 /**
7597 * insn_get_prefixes - scan x86 instruction prefix bytes
7698 * @insn: &struct insn containing instruction
....@@ -78,8 +100,12 @@
78100 * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
79101 * to point to the (first) opcode. No effect if @insn->prefixes.got
80102 * is already set.
103
+ *
104
+ * * Returns:
105
+ * 0: on success
106
+ * < 0: on error
81107 */
82
-void insn_get_prefixes(struct insn *insn)
108
+int insn_get_prefixes(struct insn *insn)
83109 {
84110 struct insn_field *prefixes = &insn->prefixes;
85111 insn_attr_t attr;
....@@ -87,7 +113,9 @@
87113 int i, nb;
88114
89115 if (prefixes->got)
90
- return;
116
+ return 0;
117
+
118
+ insn_get_emulate_prefix(insn);
91119
92120 nb = 0;
93121 lb = 0;
....@@ -196,8 +224,10 @@
196224
197225 prefixes->got = 1;
198226
227
+ return 0;
228
+
199229 err_out:
200
- return;
230
+ return -ENODATA;
201231 }
202232
203233 /**
....@@ -209,16 +239,25 @@
209239 * If necessary, first collects any preceding (prefix) bytes.
210240 * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
211241 * is already 1.
242
+ *
243
+ * Returns:
244
+ * 0: on success
245
+ * < 0: on error
212246 */
213
-void insn_get_opcode(struct insn *insn)
247
+int insn_get_opcode(struct insn *insn)
214248 {
215249 struct insn_field *opcode = &insn->opcode;
250
+ int pfx_id, ret;
216251 insn_byte_t op;
217
- int pfx_id;
252
+
218253 if (opcode->got)
219
- return;
220
- if (!insn->prefixes.got)
221
- insn_get_prefixes(insn);
254
+ return 0;
255
+
256
+ if (!insn->prefixes.got) {
257
+ ret = insn_get_prefixes(insn);
258
+ if (ret)
259
+ return ret;
260
+ }
222261
223262 /* Get first opcode */
224263 op = get_next(insn_byte_t, insn);
....@@ -233,9 +272,13 @@
233272 insn->attr = inat_get_avx_attribute(op, m, p);
234273 if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
235274 (!inat_accept_vex(insn->attr) &&
236
- !inat_is_group(insn->attr)))
237
- insn->attr = 0; /* This instruction is bad */
238
- goto end; /* VEX has only 1 byte for opcode */
275
+ !inat_is_group(insn->attr))) {
276
+ /* This instruction is bad */
277
+ insn->attr = 0;
278
+ return -EINVAL;
279
+ }
280
+ /* VEX has only 1 byte for opcode */
281
+ goto end;
239282 }
240283
241284 insn->attr = inat_get_opcode_attribute(op);
....@@ -246,13 +289,18 @@
246289 pfx_id = insn_last_prefix_id(insn);
247290 insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
248291 }
249
- if (inat_must_vex(insn->attr))
250
- insn->attr = 0; /* This instruction is bad */
292
+
293
+ if (inat_must_vex(insn->attr)) {
294
+ /* This instruction is bad */
295
+ insn->attr = 0;
296
+ return -EINVAL;
297
+ }
251298 end:
252299 opcode->got = 1;
300
+ return 0;
253301
254302 err_out:
255
- return;
303
+ return -ENODATA;
256304 }
257305
258306 /**
....@@ -262,15 +310,25 @@
262310 * Populates @insn->modrm and updates @insn->next_byte to point past the
263311 * ModRM byte, if any. If necessary, first collects the preceding bytes
264312 * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
313
+ *
314
+ * Returns:
315
+ * 0: on success
316
+ * < 0: on error
265317 */
266
-void insn_get_modrm(struct insn *insn)
318
+int insn_get_modrm(struct insn *insn)
267319 {
268320 struct insn_field *modrm = &insn->modrm;
269321 insn_byte_t pfx_id, mod;
322
+ int ret;
323
+
270324 if (modrm->got)
271
- return;
272
- if (!insn->opcode.got)
273
- insn_get_opcode(insn);
325
+ return 0;
326
+
327
+ if (!insn->opcode.got) {
328
+ ret = insn_get_opcode(insn);
329
+ if (ret)
330
+ return ret;
331
+ }
274332
275333 if (inat_has_modrm(insn->attr)) {
276334 mod = get_next(insn_byte_t, insn);
....@@ -280,17 +338,22 @@
280338 pfx_id = insn_last_prefix_id(insn);
281339 insn->attr = inat_get_group_attribute(mod, pfx_id,
282340 insn->attr);
283
- if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
284
- insn->attr = 0; /* This is bad */
341
+ if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) {
342
+ /* Bad insn */
343
+ insn->attr = 0;
344
+ return -EINVAL;
345
+ }
285346 }
286347 }
287348
288349 if (insn->x86_64 && inat_is_force64(insn->attr))
289350 insn->opnd_bytes = 8;
351
+
290352 modrm->got = 1;
353
+ return 0;
291354
292355 err_out:
293
- return;
356
+ return -ENODATA;
294357 }
295358
296359
....@@ -304,11 +367,16 @@
304367 int insn_rip_relative(struct insn *insn)
305368 {
306369 struct insn_field *modrm = &insn->modrm;
370
+ int ret;
307371
308372 if (!insn->x86_64)
309373 return 0;
310
- if (!modrm->got)
311
- insn_get_modrm(insn);
374
+
375
+ if (!modrm->got) {
376
+ ret = insn_get_modrm(insn);
377
+ if (ret)
378
+ return 0;
379
+ }
312380 /*
313381 * For rip-relative instructions, the mod field (top 2 bits)
314382 * is zero and the r/m field (bottom 3 bits) is 0x5.
....@@ -322,15 +390,25 @@
322390 *
323391 * If necessary, first collects the instruction up to and including the
324392 * ModRM byte.
393
+ *
394
+ * Returns:
395
+ * 0: if decoding succeeded
396
+ * < 0: otherwise.
325397 */
326
-void insn_get_sib(struct insn *insn)
398
+int insn_get_sib(struct insn *insn)
327399 {
328400 insn_byte_t modrm;
401
+ int ret;
329402
330403 if (insn->sib.got)
331
- return;
332
- if (!insn->modrm.got)
333
- insn_get_modrm(insn);
404
+ return 0;
405
+
406
+ if (!insn->modrm.got) {
407
+ ret = insn_get_modrm(insn);
408
+ if (ret)
409
+ return ret;
410
+ }
411
+
334412 if (insn->modrm.nbytes) {
335413 modrm = (insn_byte_t)insn->modrm.value;
336414 if (insn->addr_bytes != 2 &&
....@@ -341,8 +419,10 @@
341419 }
342420 insn->sib.got = 1;
343421
422
+ return 0;
423
+
344424 err_out:
345
- return;
425
+ return -ENODATA;
346426 }
347427
348428
....@@ -353,15 +433,25 @@
353433 * If necessary, first collects the instruction up to and including the
354434 * SIB byte.
355435 * Displacement value is sign-expanded.
436
+ *
437
+ * * Returns:
438
+ * 0: if decoding succeeded
439
+ * < 0: otherwise.
356440 */
357
-void insn_get_displacement(struct insn *insn)
441
+int insn_get_displacement(struct insn *insn)
358442 {
359443 insn_byte_t mod, rm, base;
444
+ int ret;
360445
361446 if (insn->displacement.got)
362
- return;
363
- if (!insn->sib.got)
364
- insn_get_sib(insn);
447
+ return 0;
448
+
449
+ if (!insn->sib.got) {
450
+ ret = insn_get_sib(insn);
451
+ if (ret)
452
+ return ret;
453
+ }
454
+
365455 if (insn->modrm.nbytes) {
366456 /*
367457 * Interpreting the modrm byte:
....@@ -404,9 +494,10 @@
404494 }
405495 out:
406496 insn->displacement.got = 1;
497
+ return 0;
407498
408499 err_out:
409
- return;
500
+ return -ENODATA;
410501 }
411502
412503 /* Decode moffset16/32/64. Return 0 if failed */
....@@ -517,20 +608,30 @@
517608 }
518609
519610 /**
520
- * insn_get_immediate() - Get the immediates of instruction
611
+ * insn_get_immediate() - Get the immediate in an instruction
521612 * @insn: &struct insn containing instruction
522613 *
523614 * If necessary, first collects the instruction up to and including the
524615 * displacement bytes.
525616 * Basically, most of immediates are sign-expanded. Unsigned-value can be
526
- * get by bit masking with ((1 << (nbytes * 8)) - 1)
617
+ * computed by bit masking with ((1 << (nbytes * 8)) - 1)
618
+ *
619
+ * Returns:
620
+ * 0: on success
621
+ * < 0: on error
527622 */
528
-void insn_get_immediate(struct insn *insn)
623
+int insn_get_immediate(struct insn *insn)
529624 {
625
+ int ret;
626
+
530627 if (insn->immediate.got)
531
- return;
532
- if (!insn->displacement.got)
533
- insn_get_displacement(insn);
628
+ return 0;
629
+
630
+ if (!insn->displacement.got) {
631
+ ret = insn_get_displacement(insn);
632
+ if (ret)
633
+ return ret;
634
+ }
534635
535636 if (inat_has_moffset(insn->attr)) {
536637 if (!__get_moffset(insn))
....@@ -583,9 +684,10 @@
583684 }
584685 done:
585686 insn->immediate.got = 1;
687
+ return 0;
586688
587689 err_out:
588
- return;
690
+ return -ENODATA;
589691 }
590692
591693 /**
....@@ -594,13 +696,58 @@
594696 *
595697 * If necessary, first collects the instruction up to and including the
596698 * immediates bytes.
597
- */
598
-void insn_get_length(struct insn *insn)
699
+ *
700
+ * Returns:
701
+ * - 0 on success
702
+ * - < 0 on error
703
+*/
704
+int insn_get_length(struct insn *insn)
599705 {
706
+ int ret;
707
+
600708 if (insn->length)
601
- return;
602
- if (!insn->immediate.got)
603
- insn_get_immediate(insn);
709
+ return 0;
710
+
711
+ if (!insn->immediate.got) {
712
+ ret = insn_get_immediate(insn);
713
+ if (ret)
714
+ return ret;
715
+ }
716
+
604717 insn->length = (unsigned char)((unsigned long)insn->next_byte
605718 - (unsigned long)insn->kaddr);
719
+
720
+ return 0;
721
+}
722
+
723
+/**
724
+ * insn_decode() - Decode an x86 instruction
725
+ * @insn: &struct insn to be initialized
726
+ * @kaddr: address (in kernel memory) of instruction (or copy thereof)
727
+ * @buf_len: length of the insn buffer at @kaddr
728
+ * @m: insn mode, see enum insn_mode
729
+ *
730
+ * Returns:
731
+ * 0: if decoding succeeded
732
+ * < 0: otherwise.
733
+ */
734
+int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum insn_mode m)
735
+{
736
+ int ret;
737
+
738
+/* #define INSN_MODE_KERN -1 __ignore_sync_check__ mode is only valid in the kernel */
739
+
740
+ if (m == INSN_MODE_KERN)
741
+ insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
742
+ else
743
+ insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);
744
+
745
+ ret = insn_get_length(insn);
746
+ if (ret)
747
+ return ret;
748
+
749
+ if (insn_complete(insn))
750
+ return 0;
751
+
752
+ return -EINVAL;
606753 }