This source file includes following definitions.
- is_string_insn
- get_seg_reg_override_idx
- check_seg_overrides
- resolve_default_seg
- resolve_seg_reg
- get_segment_selector
- get_reg_offset
- get_reg_offset_16
- get_desc
- insn_get_seg_base
- get_seg_limit
- insn_get_code_seg_params
- insn_get_modrm_rm_off
- get_seg_base_limit
- get_eff_addr_reg
- get_eff_addr_modrm
- get_eff_addr_modrm_16
- get_eff_addr_sib
- get_addr_ref_16
- get_addr_ref_32
- get_addr_ref_64
- get_addr_ref_64
- insn_get_addr_ref
1
2
3
4
5
6 #include <linux/kernel.h>
7 #include <linux/string.h>
8 #include <linux/ratelimit.h>
9 #include <linux/mmu_context.h>
10 #include <asm/desc_defs.h>
11 #include <asm/desc.h>
12 #include <asm/inat.h>
13 #include <asm/insn.h>
14 #include <asm/insn-eval.h>
15 #include <asm/ldt.h>
16 #include <asm/vm86.h>
17
18 #undef pr_fmt
19 #define pr_fmt(fmt) "insn: " fmt
20
21 enum reg_type {
22 REG_TYPE_RM = 0,
23 REG_TYPE_INDEX,
24 REG_TYPE_BASE,
25 };
26
27
28
29
30
31
32
33
34
35
36
37 static bool is_string_insn(struct insn *insn)
38 {
39 insn_get_opcode(insn);
40
41
42 if (insn->opcode.nbytes != 1)
43 return false;
44
45 switch (insn->opcode.bytes[0]) {
46 case 0x6c ... 0x6f:
47 case 0xa4 ... 0xa7:
48 case 0xaa ... 0xaf:
49 return true;
50 default:
51 return false;
52 }
53 }
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 static int get_seg_reg_override_idx(struct insn *insn)
70 {
71 int idx = INAT_SEG_REG_DEFAULT;
72 int num_overrides = 0, i;
73
74 insn_get_prefixes(insn);
75
76
77 for (i = 0; i < insn->prefixes.nbytes; i++) {
78 insn_attr_t attr;
79
80 attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]);
81 switch (attr) {
82 case INAT_MAKE_PREFIX(INAT_PFX_CS):
83 idx = INAT_SEG_REG_CS;
84 num_overrides++;
85 break;
86 case INAT_MAKE_PREFIX(INAT_PFX_SS):
87 idx = INAT_SEG_REG_SS;
88 num_overrides++;
89 break;
90 case INAT_MAKE_PREFIX(INAT_PFX_DS):
91 idx = INAT_SEG_REG_DS;
92 num_overrides++;
93 break;
94 case INAT_MAKE_PREFIX(INAT_PFX_ES):
95 idx = INAT_SEG_REG_ES;
96 num_overrides++;
97 break;
98 case INAT_MAKE_PREFIX(INAT_PFX_FS):
99 idx = INAT_SEG_REG_FS;
100 num_overrides++;
101 break;
102 case INAT_MAKE_PREFIX(INAT_PFX_GS):
103 idx = INAT_SEG_REG_GS;
104 num_overrides++;
105 break;
106
107 }
108 }
109
110
111 if (num_overrides > 1)
112 return -EINVAL;
113
114 return idx;
115 }
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 static bool check_seg_overrides(struct insn *insn, int regoff)
132 {
133 if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn))
134 return false;
135
136 return true;
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off)
157 {
158 if (user_64bit_mode(regs))
159 return INAT_SEG_REG_IGNORE;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 switch (off) {
175 case offsetof(struct pt_regs, ax):
176 case offsetof(struct pt_regs, cx):
177 case offsetof(struct pt_regs, dx):
178
179 if (insn->addr_bytes == 2)
180 return -EINVAL;
181
182
183
184 case -EDOM:
185 case offsetof(struct pt_regs, bx):
186 case offsetof(struct pt_regs, si):
187 return INAT_SEG_REG_DS;
188
189 case offsetof(struct pt_regs, di):
190 if (is_string_insn(insn))
191 return INAT_SEG_REG_ES;
192 return INAT_SEG_REG_DS;
193
194 case offsetof(struct pt_regs, bp):
195 case offsetof(struct pt_regs, sp):
196 return INAT_SEG_REG_SS;
197
198 case offsetof(struct pt_regs, ip):
199 return INAT_SEG_REG_CS;
200
201 default:
202 return -EINVAL;
203 }
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258 static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
259 {
260 int idx;
261
262
263
264
265
266
267
268 if (regoff == offsetof(struct pt_regs, ip)) {
269 if (user_64bit_mode(regs))
270 return INAT_SEG_REG_IGNORE;
271 else
272 return INAT_SEG_REG_CS;
273 }
274
275 if (!insn)
276 return -EINVAL;
277
278 if (!check_seg_overrides(insn, regoff))
279 return resolve_default_seg(insn, regs, regoff);
280
281 idx = get_seg_reg_override_idx(insn);
282 if (idx < 0)
283 return idx;
284
285 if (idx == INAT_SEG_REG_DEFAULT)
286 return resolve_default_seg(insn, regs, regoff);
287
288
289
290
291
292 if (user_64bit_mode(regs)) {
293 if (idx != INAT_SEG_REG_FS &&
294 idx != INAT_SEG_REG_GS)
295 idx = INAT_SEG_REG_IGNORE;
296 }
297
298 return idx;
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
321 {
322 #ifdef CONFIG_X86_64
323 unsigned short sel;
324
325 switch (seg_reg_idx) {
326 case INAT_SEG_REG_IGNORE:
327 return 0;
328 case INAT_SEG_REG_CS:
329 return (unsigned short)(regs->cs & 0xffff);
330 case INAT_SEG_REG_SS:
331 return (unsigned short)(regs->ss & 0xffff);
332 case INAT_SEG_REG_DS:
333 savesegment(ds, sel);
334 return sel;
335 case INAT_SEG_REG_ES:
336 savesegment(es, sel);
337 return sel;
338 case INAT_SEG_REG_FS:
339 savesegment(fs, sel);
340 return sel;
341 case INAT_SEG_REG_GS:
342 savesegment(gs, sel);
343 return sel;
344 default:
345 return -EINVAL;
346 }
347 #else
348 struct kernel_vm86_regs *vm86regs = (struct kernel_vm86_regs *)regs;
349
350 if (v8086_mode(regs)) {
351 switch (seg_reg_idx) {
352 case INAT_SEG_REG_CS:
353 return (unsigned short)(regs->cs & 0xffff);
354 case INAT_SEG_REG_SS:
355 return (unsigned short)(regs->ss & 0xffff);
356 case INAT_SEG_REG_DS:
357 return vm86regs->ds;
358 case INAT_SEG_REG_ES:
359 return vm86regs->es;
360 case INAT_SEG_REG_FS:
361 return vm86regs->fs;
362 case INAT_SEG_REG_GS:
363 return vm86regs->gs;
364 case INAT_SEG_REG_IGNORE:
365
366 default:
367 return -EINVAL;
368 }
369 }
370
371 switch (seg_reg_idx) {
372 case INAT_SEG_REG_CS:
373 return (unsigned short)(regs->cs & 0xffff);
374 case INAT_SEG_REG_SS:
375 return (unsigned short)(regs->ss & 0xffff);
376 case INAT_SEG_REG_DS:
377 return (unsigned short)(regs->ds & 0xffff);
378 case INAT_SEG_REG_ES:
379 return (unsigned short)(regs->es & 0xffff);
380 case INAT_SEG_REG_FS:
381 return (unsigned short)(regs->fs & 0xffff);
382 case INAT_SEG_REG_GS:
383
384
385
386
387 return get_user_gs(regs);
388 case INAT_SEG_REG_IGNORE:
389
390 default:
391 return -EINVAL;
392 }
393 #endif
394 }
395
396 static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
397 enum reg_type type)
398 {
399 int regno = 0;
400
401 static const int regoff[] = {
402 offsetof(struct pt_regs, ax),
403 offsetof(struct pt_regs, cx),
404 offsetof(struct pt_regs, dx),
405 offsetof(struct pt_regs, bx),
406 offsetof(struct pt_regs, sp),
407 offsetof(struct pt_regs, bp),
408 offsetof(struct pt_regs, si),
409 offsetof(struct pt_regs, di),
410 #ifdef CONFIG_X86_64
411 offsetof(struct pt_regs, r8),
412 offsetof(struct pt_regs, r9),
413 offsetof(struct pt_regs, r10),
414 offsetof(struct pt_regs, r11),
415 offsetof(struct pt_regs, r12),
416 offsetof(struct pt_regs, r13),
417 offsetof(struct pt_regs, r14),
418 offsetof(struct pt_regs, r15),
419 #endif
420 };
421 int nr_registers = ARRAY_SIZE(regoff);
422
423
424
425
426 if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64)
427 nr_registers -= 8;
428
429 switch (type) {
430 case REG_TYPE_RM:
431 regno = X86_MODRM_RM(insn->modrm.value);
432
433
434
435
436
437 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5)
438 return -EDOM;
439
440 if (X86_REX_B(insn->rex_prefix.value))
441 regno += 8;
442 break;
443
444 case REG_TYPE_INDEX:
445 regno = X86_SIB_INDEX(insn->sib.value);
446 if (X86_REX_X(insn->rex_prefix.value))
447 regno += 8;
448
449
450
451
452
453
454
455 if (X86_MODRM_MOD(insn->modrm.value) != 3 && regno == 4)
456 return -EDOM;
457 break;
458
459 case REG_TYPE_BASE:
460 regno = X86_SIB_BASE(insn->sib.value);
461
462
463
464
465
466 if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5)
467 return -EDOM;
468
469 if (X86_REX_B(insn->rex_prefix.value))
470 regno += 8;
471 break;
472
473 default:
474 pr_err_ratelimited("invalid register type: %d\n", type);
475 return -EINVAL;
476 }
477
478 if (regno >= nr_registers) {
479 WARN_ONCE(1, "decoded an instruction with an invalid register");
480 return -EINVAL;
481 }
482 return regoff[regno];
483 }
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502 static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs,
503 int *offs1, int *offs2)
504 {
505
506
507
508
509
510 static const int regoff1[] = {
511 offsetof(struct pt_regs, bx),
512 offsetof(struct pt_regs, bx),
513 offsetof(struct pt_regs, bp),
514 offsetof(struct pt_regs, bp),
515 offsetof(struct pt_regs, si),
516 offsetof(struct pt_regs, di),
517 offsetof(struct pt_regs, bp),
518 offsetof(struct pt_regs, bx),
519 };
520
521 static const int regoff2[] = {
522 offsetof(struct pt_regs, si),
523 offsetof(struct pt_regs, di),
524 offsetof(struct pt_regs, si),
525 offsetof(struct pt_regs, di),
526 -EDOM,
527 -EDOM,
528 -EDOM,
529 -EDOM,
530 };
531
532 if (!offs1 || !offs2)
533 return -EINVAL;
534
535
536 if (X86_MODRM_MOD(insn->modrm.value) == 3) {
537 *offs1 = insn_get_modrm_rm_off(insn, regs);
538 *offs2 = -EDOM;
539 return 0;
540 }
541
542 *offs1 = regoff1[X86_MODRM_RM(insn->modrm.value)];
543 *offs2 = regoff2[X86_MODRM_RM(insn->modrm.value)];
544
545
546
547
548
549
550
551
552 if ((X86_MODRM_MOD(insn->modrm.value) == 0) &&
553 (X86_MODRM_RM(insn->modrm.value) == 6))
554 *offs1 = -EDOM;
555
556 return 0;
557 }
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573 static bool get_desc(struct desc_struct *out, unsigned short sel)
574 {
575 struct desc_ptr gdt_desc = {0, 0};
576 unsigned long desc_base;
577
578 #ifdef CONFIG_MODIFY_LDT_SYSCALL
579 if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) {
580 bool success = false;
581 struct ldt_struct *ldt;
582
583
584 sel >>= 3;
585
586 mutex_lock(¤t->active_mm->context.lock);
587 ldt = current->active_mm->context.ldt;
588 if (ldt && sel < ldt->nr_entries) {
589 *out = ldt->entries[sel];
590 success = true;
591 }
592
593 mutex_unlock(¤t->active_mm->context.lock);
594
595 return success;
596 }
597 #endif
598 native_store_gdt(&gdt_desc);
599
600
601
602
603
604
605
606
607 desc_base = sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK);
608
609 if (desc_base > gdt_desc.size)
610 return false;
611
612 *out = *(struct desc_struct *)(gdt_desc.address + desc_base);
613 return true;
614 }
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633 unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)
634 {
635 struct desc_struct desc;
636 short sel;
637
638 sel = get_segment_selector(regs, seg_reg_idx);
639 if (sel < 0)
640 return -1L;
641
642 if (v8086_mode(regs))
643
644
645
646
647 return (unsigned long)(sel << 4);
648
649 if (user_64bit_mode(regs)) {
650
651
652
653
654 unsigned long base;
655
656 if (seg_reg_idx == INAT_SEG_REG_FS)
657 rdmsrl(MSR_FS_BASE, base);
658 else if (seg_reg_idx == INAT_SEG_REG_GS)
659
660
661
662
663 rdmsrl(MSR_KERNEL_GS_BASE, base);
664 else
665 base = 0;
666 return base;
667 }
668
669
670 if (!sel)
671 return -1L;
672
673 if (!get_desc(&desc, sel))
674 return -1L;
675
676 return get_desc_base(&desc);
677 }
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696 static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx)
697 {
698 struct desc_struct desc;
699 unsigned long limit;
700 short sel;
701
702 sel = get_segment_selector(regs, seg_reg_idx);
703 if (sel < 0)
704 return 0;
705
706 if (user_64bit_mode(regs) || v8086_mode(regs))
707 return -1L;
708
709 if (!sel)
710 return 0;
711
712 if (!get_desc(&desc, sel))
713 return 0;
714
715
716
717
718
719
720
721 limit = get_desc_limit(&desc);
722 if (desc.g)
723 limit = (limit << 12) + 0xfff;
724
725 return limit;
726 }
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744 int insn_get_code_seg_params(struct pt_regs *regs)
745 {
746 struct desc_struct desc;
747 short sel;
748
749 if (v8086_mode(regs))
750
751 return INSN_CODE_SEG_PARAMS(2, 2);
752
753 sel = get_segment_selector(regs, INAT_SEG_REG_CS);
754 if (sel < 0)
755 return sel;
756
757 if (!get_desc(&desc, sel))
758 return -EINVAL;
759
760
761
762
763
764
765 if (!(desc.type & BIT(3)))
766 return -EINVAL;
767
768 switch ((desc.l << 1) | desc.d) {
769 case 0:
770
771
772
773 return INSN_CODE_SEG_PARAMS(2, 2);
774 case 1:
775
776
777
778 return INSN_CODE_SEG_PARAMS(4, 4);
779 case 2:
780
781
782
783 return INSN_CODE_SEG_PARAMS(4, 8);
784 case 3:
785
786 default:
787 return -EINVAL;
788 }
789 }
790
791
792
793
794
795
796
797
798
799
800
801
802
803 int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs)
804 {
805 return get_reg_offset(insn, regs, REG_TYPE_RM);
806 }
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829 static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs,
830 int regoff, unsigned long *base,
831 unsigned long *limit)
832 {
833 int seg_reg_idx;
834
835 if (!base)
836 return -EINVAL;
837
838 seg_reg_idx = resolve_seg_reg(insn, regs, regoff);
839 if (seg_reg_idx < 0)
840 return seg_reg_idx;
841
842 *base = insn_get_seg_base(regs, seg_reg_idx);
843 if (*base == -1L)
844 return -EINVAL;
845
846 if (!limit)
847 return 0;
848
849 *limit = get_seg_limit(regs, seg_reg_idx);
850 if (!(*limit))
851 return -EINVAL;
852
853 return 0;
854 }
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879 static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs,
880 int *regoff, long *eff_addr)
881 {
882 insn_get_modrm(insn);
883
884 if (!insn->modrm.nbytes)
885 return -EINVAL;
886
887 if (X86_MODRM_MOD(insn->modrm.value) != 3)
888 return -EINVAL;
889
890 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM);
891 if (*regoff < 0)
892 return -EINVAL;
893
894
895 if (insn->addr_bytes == 2)
896 *eff_addr = regs_get_register(regs, *regoff) & 0xffff;
897 else if (insn->addr_bytes == 4)
898 *eff_addr = regs_get_register(regs, *regoff) & 0xffffffff;
899 else
900 *eff_addr = regs_get_register(regs, *regoff);
901
902 return 0;
903 }
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927 static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs,
928 int *regoff, long *eff_addr)
929 {
930 long tmp;
931
932 if (insn->addr_bytes != 8 && insn->addr_bytes != 4)
933 return -EINVAL;
934
935 insn_get_modrm(insn);
936
937 if (!insn->modrm.nbytes)
938 return -EINVAL;
939
940 if (X86_MODRM_MOD(insn->modrm.value) > 2)
941 return -EINVAL;
942
943 *regoff = get_reg_offset(insn, regs, REG_TYPE_RM);
944
945
946
947
948
949
950 if (*regoff == -EDOM) {
951 if (user_64bit_mode(regs))
952 tmp = regs->ip + insn->length;
953 else
954 tmp = 0;
955 } else if (*regoff < 0) {
956 return -EINVAL;
957 } else {
958 tmp = regs_get_register(regs, *regoff);
959 }
960
961 if (insn->addr_bytes == 4) {
962 int addr32 = (int)(tmp & 0xffffffff) + insn->displacement.value;
963
964 *eff_addr = addr32 & 0xffffffff;
965 } else {
966 *eff_addr = tmp + insn->displacement.value;
967 }
968
969 return 0;
970 }
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994 static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs,
995 int *regoff, short *eff_addr)
996 {
997 int addr_offset1, addr_offset2, ret;
998 short addr1 = 0, addr2 = 0, displacement;
999
1000 if (insn->addr_bytes != 2)
1001 return -EINVAL;
1002
1003 insn_get_modrm(insn);
1004
1005 if (!insn->modrm.nbytes)
1006 return -EINVAL;
1007
1008 if (X86_MODRM_MOD(insn->modrm.value) > 2)
1009 return -EINVAL;
1010
1011 ret = get_reg_offset_16(insn, regs, &addr_offset1, &addr_offset2);
1012 if (ret < 0)
1013 return -EINVAL;
1014
1015
1016
1017
1018
1019
1020 if (addr_offset1 != -EDOM)
1021 addr1 = regs_get_register(regs, addr_offset1) & 0xffff;
1022
1023 if (addr_offset2 != -EDOM)
1024 addr2 = regs_get_register(regs, addr_offset2) & 0xffff;
1025
1026 displacement = insn->displacement.value & 0xffff;
1027 *eff_addr = addr1 + addr2 + displacement;
1028
1029
1030
1031
1032
1033
1034
1035 *regoff = addr_offset1;
1036
1037 return 0;
1038 }
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs,
1063 int *base_offset, long *eff_addr)
1064 {
1065 long base, indx;
1066 int indx_offset;
1067
1068 if (insn->addr_bytes != 8 && insn->addr_bytes != 4)
1069 return -EINVAL;
1070
1071 insn_get_modrm(insn);
1072
1073 if (!insn->modrm.nbytes)
1074 return -EINVAL;
1075
1076 if (X86_MODRM_MOD(insn->modrm.value) > 2)
1077 return -EINVAL;
1078
1079 insn_get_sib(insn);
1080
1081 if (!insn->sib.nbytes)
1082 return -EINVAL;
1083
1084 *base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE);
1085 indx_offset = get_reg_offset(insn, regs, REG_TYPE_INDEX);
1086
1087
1088
1089
1090
1091
1092 if (*base_offset == -EDOM)
1093 base = 0;
1094 else if (*base_offset < 0)
1095 return -EINVAL;
1096 else
1097 base = regs_get_register(regs, *base_offset);
1098
1099 if (indx_offset == -EDOM)
1100 indx = 0;
1101 else if (indx_offset < 0)
1102 return -EINVAL;
1103 else
1104 indx = regs_get_register(regs, indx_offset);
1105
1106 if (insn->addr_bytes == 4) {
1107 int addr32, base32, idx32;
1108
1109 base32 = base & 0xffffffff;
1110 idx32 = indx & 0xffffffff;
1111
1112 addr32 = base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value));
1113 addr32 += insn->displacement.value;
1114
1115 *eff_addr = addr32 & 0xffffffff;
1116 } else {
1117 *eff_addr = base + indx * (1 << X86_SIB_SCALE(insn->sib.value));
1118 *eff_addr += insn->displacement.value;
1119 }
1120
1121 return 0;
1122 }
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141 static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs)
1142 {
1143 unsigned long linear_addr = -1L, seg_base, seg_limit;
1144 int ret, regoff;
1145 short eff_addr;
1146 long tmp;
1147
1148 insn_get_modrm(insn);
1149 insn_get_displacement(insn);
1150
1151 if (insn->addr_bytes != 2)
1152 goto out;
1153
1154 if (X86_MODRM_MOD(insn->modrm.value) == 3) {
1155 ret = get_eff_addr_reg(insn, regs, ®off, &tmp);
1156 if (ret)
1157 goto out;
1158
1159 eff_addr = tmp;
1160 } else {
1161 ret = get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr);
1162 if (ret)
1163 goto out;
1164 }
1165
1166 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit);
1167 if (ret)
1168 goto out;
1169
1170
1171
1172
1173
1174
1175
1176 if ((unsigned long)(eff_addr & 0xffff) > seg_limit)
1177 goto out;
1178
1179 linear_addr = (unsigned long)(eff_addr & 0xffff) + seg_base;
1180
1181
1182 if (v8086_mode(regs))
1183 linear_addr &= 0xfffff;
1184
1185 out:
1186 return (void __user *)linear_addr;
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205 static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs)
1206 {
1207 unsigned long linear_addr = -1L, seg_base, seg_limit;
1208 int eff_addr, regoff;
1209 long tmp;
1210 int ret;
1211
1212 if (insn->addr_bytes != 4)
1213 goto out;
1214
1215 if (X86_MODRM_MOD(insn->modrm.value) == 3) {
1216 ret = get_eff_addr_reg(insn, regs, ®off, &tmp);
1217 if (ret)
1218 goto out;
1219
1220 eff_addr = tmp;
1221
1222 } else {
1223 if (insn->sib.nbytes) {
1224 ret = get_eff_addr_sib(insn, regs, ®off, &tmp);
1225 if (ret)
1226 goto out;
1227
1228 eff_addr = tmp;
1229 } else {
1230 ret = get_eff_addr_modrm(insn, regs, ®off, &tmp);
1231 if (ret)
1232 goto out;
1233
1234 eff_addr = tmp;
1235 }
1236 }
1237
1238 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit);
1239 if (ret)
1240 goto out;
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 if (!user_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit))
1254 goto out;
1255
1256
1257
1258
1259
1260 if (v8086_mode(regs) && (eff_addr & ~0xffff))
1261 goto out;
1262
1263
1264
1265
1266
1267
1268 linear_addr = (unsigned long)(eff_addr & 0xffffffff) + seg_base;
1269
1270
1271 if (v8086_mode(regs))
1272 linear_addr &= 0xfffff;
1273
1274 out:
1275 return (void __user *)linear_addr;
1276 }
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293 #ifndef CONFIG_X86_64
1294 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs)
1295 {
1296 return (void __user *)-1L;
1297 }
1298 #else
1299 static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs)
1300 {
1301 unsigned long linear_addr = -1L, seg_base;
1302 int regoff, ret;
1303 long eff_addr;
1304
1305 if (insn->addr_bytes != 8)
1306 goto out;
1307
1308 if (X86_MODRM_MOD(insn->modrm.value) == 3) {
1309 ret = get_eff_addr_reg(insn, regs, ®off, &eff_addr);
1310 if (ret)
1311 goto out;
1312
1313 } else {
1314 if (insn->sib.nbytes) {
1315 ret = get_eff_addr_sib(insn, regs, ®off, &eff_addr);
1316 if (ret)
1317 goto out;
1318 } else {
1319 ret = get_eff_addr_modrm(insn, regs, ®off, &eff_addr);
1320 if (ret)
1321 goto out;
1322 }
1323
1324 }
1325
1326 ret = get_seg_base_limit(insn, regs, regoff, &seg_base, NULL);
1327 if (ret)
1328 goto out;
1329
1330 linear_addr = (unsigned long)eff_addr + seg_base;
1331
1332 out:
1333 return (void __user *)linear_addr;
1334 }
1335 #endif
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs)
1353 {
1354 if (!insn || !regs)
1355 return (void __user *)-1L;
1356
1357 switch (insn->addr_bytes) {
1358 case 2:
1359 return get_addr_ref_16(insn, regs);
1360 case 4:
1361 return get_addr_ref_32(insn, regs);
1362 case 8:
1363 return get_addr_ref_64(insn, regs);
1364 default:
1365 return (void __user *)-1L;
1366 }
1367 }