^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Utility functions for x86 operand and address decoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) Intel Corporation 2017
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/desc_defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/desc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/inat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/insn-eval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/ldt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/vm86.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #undef pr_fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define pr_fmt(fmt) "insn: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) enum reg_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) REG_TYPE_RM = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) REG_TYPE_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) REG_TYPE_INDEX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) REG_TYPE_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * is_string_insn() - Determine if instruction is a string instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * @insn: Instruction containing the opcode to inspect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * true if the instruction, determined by the opcode, is any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * string instructions as defined in the Intel Software Development manual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * False otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static bool is_string_insn(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) insn_get_opcode(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* All string instructions have a 1-byte opcode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (insn->opcode.nbytes != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) switch (insn->opcode.bytes[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) case 0x6c ... 0x6f: /* INS, OUTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) case 0xa4 ... 0xa7: /* MOVS, CMPS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) case 0xaa ... 0xaf: /* STOS, LODS, SCAS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * insn_has_rep_prefix() - Determine if instruction has a REP prefix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @insn: Instruction containing the prefix to inspect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * true if the instruction has a REP prefix, false if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bool insn_has_rep_prefix(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) insn_byte_t p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) insn_get_prefixes(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) for_each_insn_prefix(insn, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (p == 0xf2 || p == 0xf3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * get_seg_reg_override_idx() - obtain segment register override index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * @insn: Valid instruction with segment override prefixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * Inspect the instruction prefixes in @insn and find segment overrides, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * A constant identifying the segment register to use, among CS, SS, DS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * ES, FS, or GS. INAT_SEG_REG_DEFAULT is returned if no segment override
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * prefixes were found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * -EINVAL in case of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int get_seg_reg_override_idx(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int idx = INAT_SEG_REG_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int num_overrides = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) insn_byte_t p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) insn_get_prefixes(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Look for any segment override prefixes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) for_each_insn_prefix(insn, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) insn_attr_t attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) attr = inat_get_opcode_attribute(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case INAT_MAKE_PREFIX(INAT_PFX_CS):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) idx = INAT_SEG_REG_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case INAT_MAKE_PREFIX(INAT_PFX_SS):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) idx = INAT_SEG_REG_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case INAT_MAKE_PREFIX(INAT_PFX_DS):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) idx = INAT_SEG_REG_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case INAT_MAKE_PREFIX(INAT_PFX_ES):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) idx = INAT_SEG_REG_ES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case INAT_MAKE_PREFIX(INAT_PFX_FS):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) idx = INAT_SEG_REG_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) case INAT_MAKE_PREFIX(INAT_PFX_GS):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) idx = INAT_SEG_REG_GS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) num_overrides++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* No default action needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* More than one segment override prefix leads to undefined behavior. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (num_overrides > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * check_seg_overrides() - check if segment override prefixes are allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @insn: Valid instruction with segment override prefixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @regoff: Operand offset, in pt_regs, for which the check is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * For a particular register used in register-indirect addressing, determine if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * segment override prefixes can be used. Specifically, no overrides are allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * for rDI if used with a string instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * True if segment override prefixes can be used with the register indicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * in @regoff. False if otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static bool check_seg_overrides(struct insn *insn, int regoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (regoff == offsetof(struct pt_regs, di) && is_string_insn(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * resolve_default_seg() - resolve default segment register index for an operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * @insn: Instruction with opcode and address size. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @off: Operand offset, in pt_regs, for which resolution is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * Resolve the default segment register index associated with the instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * operand register indicated by @off. Such index is resolved based on defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * described in the Intel Software Development Manual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * If in protected mode, a constant identifying the segment register to use,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * among CS, SS, ES or DS. If in long mode, INAT_SEG_REG_IGNORE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * -EINVAL in case of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (any_64bit_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return INAT_SEG_REG_IGNORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Resolve the default segment register as described in Section 3.7.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * of the Intel Software Development Manual Vol. 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * + DS for all references involving r[ABCD]X, and rSI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * + If used in a string instruction, ES for rDI. Otherwise, DS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * + AX, CX and DX are not valid register operands in 16-bit address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * encodings but are valid for 32-bit and 64-bit encodings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * + -EDOM is reserved to identify for cases in which no register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * is used (i.e., displacement-only addressing). Use DS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * + SS for rSP or rBP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * + CS for rIP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) switch (off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case offsetof(struct pt_regs, ax):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case offsetof(struct pt_regs, cx):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case offsetof(struct pt_regs, dx):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Need insn to verify address size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (insn->addr_bytes == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case -EDOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case offsetof(struct pt_regs, bx):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case offsetof(struct pt_regs, si):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return INAT_SEG_REG_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case offsetof(struct pt_regs, di):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (is_string_insn(insn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return INAT_SEG_REG_ES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return INAT_SEG_REG_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case offsetof(struct pt_regs, bp):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case offsetof(struct pt_regs, sp):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return INAT_SEG_REG_SS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case offsetof(struct pt_regs, ip):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return INAT_SEG_REG_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * resolve_seg_reg() - obtain segment register index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @insn: Instruction with operands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @regoff: Operand offset, in pt_regs, used to deterimine segment register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Determine the segment register associated with the operands and, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * applicable, prefixes and the instruction pointed by @insn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * The segment register associated to an operand used in register-indirect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * addressing depends on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * a) Whether running in long mode (in such a case segments are ignored, except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * if FS or GS are used).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * b) Whether segment override prefixes can be used. Certain instructions and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * registers do not allow override prefixes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * c) Whether segment overrides prefixes are found in the instruction prefixes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * d) If there are not segment override prefixes or they cannot be used, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * default segment register associated with the operand register is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * The function checks first if segment override prefixes can be used with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * operand indicated by @regoff. If allowed, obtain such overridden segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * register index. Lastly, if not prefixes were found or cannot be used, resolve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * the segment register index to use based on the defaults described in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * Intel documentation. In long mode, all segment register indexes will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * ignored, except if overrides were found for FS or GS. All these operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * are done using helper functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * The operand register, @regoff, is represented as the offset from the base of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * pt_regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * As stated, the main use of this function is to determine the segment register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * index based on the instruction, its operands and prefixes. Hence, @insn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * must be valid. However, if @regoff indicates rIP, we don't need to inspect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * @insn at all as in this case CS is used in all cases. This case is checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * before proceeding further.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * Please note that this function does not return the value in the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * register (i.e., the segment selector) but our defined index. The segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * selector needs to be obtained using get_segment_selector() and passing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * segment register index resolved by this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * An index identifying the segment register to use, among CS, SS, DS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * ES, FS, or GS. INAT_SEG_REG_IGNORE is returned if running in long mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * -EINVAL in case of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * In the unlikely event of having to resolve the segment register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * index for rIP, do it first. Segment override prefixes should not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * be used. Hence, it is not necessary to inspect the instruction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * which may be invalid at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (regoff == offsetof(struct pt_regs, ip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (any_64bit_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return INAT_SEG_REG_IGNORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return INAT_SEG_REG_CS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (!check_seg_overrides(insn, regoff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return resolve_default_seg(insn, regs, regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) idx = get_seg_reg_override_idx(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (idx == INAT_SEG_REG_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return resolve_default_seg(insn, regs, regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * In long mode, segment override prefixes are ignored, except for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * overrides for FS and GS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (any_64bit_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (idx != INAT_SEG_REG_FS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) idx != INAT_SEG_REG_GS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) idx = INAT_SEG_REG_IGNORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * get_segment_selector() - obtain segment selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * @seg_reg_idx: Segment register index to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * Obtain the segment selector from any of the CS, SS, DS, ES, FS, GS segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * registers. In CONFIG_X86_32, the segment is obtained from either pt_regs or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * kernel_vm86_regs as applicable. In CONFIG_X86_64, CS and SS are obtained
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * from pt_regs. DS, ES, FS and GS are obtained by reading the actual CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * registers. This done for only for completeness as in CONFIG_X86_64 segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * registers are ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * Value of the segment selector, including null when running in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * long mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static short get_segment_selector(struct pt_regs *regs, int seg_reg_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned short sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) switch (seg_reg_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case INAT_SEG_REG_IGNORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case INAT_SEG_REG_CS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return (unsigned short)(regs->cs & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case INAT_SEG_REG_SS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return (unsigned short)(regs->ss & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case INAT_SEG_REG_DS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) savesegment(ds, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case INAT_SEG_REG_ES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) savesegment(es, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case INAT_SEG_REG_FS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) savesegment(fs, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case INAT_SEG_REG_GS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) savesegment(gs, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #else /* CONFIG_X86_32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct kernel_vm86_regs *vm86regs = (struct kernel_vm86_regs *)regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (v8086_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) switch (seg_reg_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case INAT_SEG_REG_CS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return (unsigned short)(regs->cs & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case INAT_SEG_REG_SS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return (unsigned short)(regs->ss & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case INAT_SEG_REG_DS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return vm86regs->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case INAT_SEG_REG_ES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return vm86regs->es;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case INAT_SEG_REG_FS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return vm86regs->fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case INAT_SEG_REG_GS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return vm86regs->gs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) case INAT_SEG_REG_IGNORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) switch (seg_reg_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case INAT_SEG_REG_CS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return (unsigned short)(regs->cs & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case INAT_SEG_REG_SS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return (unsigned short)(regs->ss & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) case INAT_SEG_REG_DS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return (unsigned short)(regs->ds & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case INAT_SEG_REG_ES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return (unsigned short)(regs->es & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case INAT_SEG_REG_FS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return (unsigned short)(regs->fs & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case INAT_SEG_REG_GS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * GS may or may not be in regs as per CONFIG_X86_32_LAZY_GS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * The macro below takes care of both cases.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return get_user_gs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case INAT_SEG_REG_IGNORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #endif /* CONFIG_X86_64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) enum reg_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int regno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static const int regoff[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) offsetof(struct pt_regs, ax),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) offsetof(struct pt_regs, cx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) offsetof(struct pt_regs, dx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) offsetof(struct pt_regs, bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) offsetof(struct pt_regs, sp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) offsetof(struct pt_regs, bp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) offsetof(struct pt_regs, si),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) offsetof(struct pt_regs, di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) offsetof(struct pt_regs, r8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) offsetof(struct pt_regs, r9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) offsetof(struct pt_regs, r10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) offsetof(struct pt_regs, r11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) offsetof(struct pt_regs, r12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) offsetof(struct pt_regs, r13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) offsetof(struct pt_regs, r14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) offsetof(struct pt_regs, r15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int nr_registers = ARRAY_SIZE(regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Don't possibly decode a 32-bit instructions as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * reading a 64-bit-only register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (IS_ENABLED(CONFIG_X86_64) && !insn->x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) nr_registers -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case REG_TYPE_RM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) regno = X86_MODRM_RM(insn->modrm.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * ModRM.mod == 0 and ModRM.rm == 5 means a 32-bit displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * follows the ModRM byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (X86_REX_B(insn->rex_prefix.value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) regno += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case REG_TYPE_REG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) regno = X86_MODRM_REG(insn->modrm.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (X86_REX_R(insn->rex_prefix.value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) regno += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) case REG_TYPE_INDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) regno = X86_SIB_INDEX(insn->sib.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (X86_REX_X(insn->rex_prefix.value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) regno += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * If ModRM.mod != 3 and SIB.index = 4 the scale*index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * portion of the address computation is null. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * true only if REX.X is 0. In such a case, the SIB index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * is used in the address computation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (X86_MODRM_MOD(insn->modrm.value) != 3 && regno == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case REG_TYPE_BASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) regno = X86_SIB_BASE(insn->sib.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * If ModRM.mod is 0 and SIB.base == 5, the base of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * register-indirect addressing is 0. In this case, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * 32-bit displacement follows the SIB byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (!X86_MODRM_MOD(insn->modrm.value) && regno == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (X86_REX_B(insn->rex_prefix.value))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) regno += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pr_err_ratelimited("invalid register type: %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (regno >= nr_registers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) WARN_ONCE(1, "decoded an instruction with an invalid register");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return regoff[regno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * get_reg_offset_16() - Obtain offset of register indicated by instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * @insn: Instruction containing ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * @offs1: Offset of the first operand register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @offs2: Offset of the second opeand register, if applicable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * Obtain the offset, in pt_regs, of the registers indicated by the ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * in @insn. This function is to be used with 16-bit address encodings. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * @offs1 and @offs2 will be written with the offset of the two registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * indicated by the instruction. In cases where any of the registers is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * referenced by the instruction, the value will be set to -EDOM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * 0 on success, -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int get_reg_offset_16(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int *offs1, int *offs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * 16-bit addressing can use one or two registers. Specifics of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * encodings are given in Table 2-1. "16-Bit Addressing Forms with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * ModR/M Byte" of the Intel Software Development Manual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static const int regoff1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) offsetof(struct pt_regs, bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) offsetof(struct pt_regs, bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) offsetof(struct pt_regs, bp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) offsetof(struct pt_regs, bp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) offsetof(struct pt_regs, si),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) offsetof(struct pt_regs, di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) offsetof(struct pt_regs, bp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) offsetof(struct pt_regs, bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static const int regoff2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) offsetof(struct pt_regs, si),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) offsetof(struct pt_regs, di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) offsetof(struct pt_regs, si),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) offsetof(struct pt_regs, di),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) -EDOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) -EDOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) -EDOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) -EDOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (!offs1 || !offs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Operand is a register, use the generic function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (X86_MODRM_MOD(insn->modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *offs1 = insn_get_modrm_rm_off(insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) *offs2 = -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) *offs1 = regoff1[X86_MODRM_RM(insn->modrm.value)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *offs2 = regoff2[X86_MODRM_RM(insn->modrm.value)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * If ModRM.mod is 0 and ModRM.rm is 110b, then we use displacement-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * only addressing. This means that no registers are involved in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * computing the effective address. Thus, ensure that the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * register offset is invalild. The second register offset is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * invalid under the aforementioned conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if ((X86_MODRM_MOD(insn->modrm.value) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) (X86_MODRM_RM(insn->modrm.value) == 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *offs1 = -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * get_desc() - Obtain contents of a segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * @out: Segment descriptor contents on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * @sel: Segment selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * Given a segment selector, obtain a pointer to the segment descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * Both global and local descriptor tables are supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * True on success, false on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * NULL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static bool get_desc(struct desc_struct *out, unsigned short sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct desc_ptr gdt_desc = {0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) unsigned long desc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #ifdef CONFIG_MODIFY_LDT_SYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) bool success = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct ldt_struct *ldt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Bits [15:3] contain the index of the desired entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) sel >>= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) mutex_lock(¤t->active_mm->context.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ldt = current->active_mm->context.ldt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (ldt && sel < ldt->nr_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *out = ldt->entries[sel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) success = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mutex_unlock(¤t->active_mm->context.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) native_store_gdt(&gdt_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * Segment descriptors have a size of 8 bytes. Thus, the index is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * multiplied by 8 to obtain the memory offset of the desired descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * from the base of the GDT. As bits [15:3] of the segment selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * contain the index, it can be regarded as multiplied by 8 already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * All that remains is to clear bits [2:0].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) desc_base = sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (desc_base > gdt_desc.size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) *out = *(struct desc_struct *)(gdt_desc.address + desc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * insn_get_seg_base() - Obtain base address of segment descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * @seg_reg_idx: Index of the segment register pointing to seg descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * Obtain the base address of the segment as indicated by the segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * pointed by the segment selector. The segment selector is obtained from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * input segment register index @seg_reg_idx.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * In protected mode, base address of the segment. Zero in long mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * except when FS or GS are used. In virtual-8086 mode, the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * selector shifted 4 bits to the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * -1L in case of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct desc_struct desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) short sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) sel = get_segment_selector(regs, seg_reg_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (v8086_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * Base is simply the segment selector shifted 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * bits to the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return (unsigned long)(sel << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (any_64bit_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Only FS or GS will have a base address, the rest of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * the segments' bases are forced to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned long base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (seg_reg_idx == INAT_SEG_REG_FS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) rdmsrl(MSR_FS_BASE, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) } else if (seg_reg_idx == INAT_SEG_REG_GS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * swapgs was called at the kernel entry point. Thus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * MSR_KERNEL_GS_BASE will have the user-space GS base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) rdmsrl(MSR_KERNEL_GS_BASE, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) rdmsrl(MSR_GS_BASE, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* In protected mode the segment selector cannot be null. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (!sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return -1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (!get_desc(&desc, sel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return -1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return get_desc_base(&desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * get_seg_limit() - Obtain the limit of a segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * @seg_reg_idx: Index of the segment register pointing to seg descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * Obtain the limit of the segment as indicated by the segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * pointed by the segment selector. The segment selector is obtained from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * input segment register index @seg_reg_idx.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * In protected mode, the limit of the segment descriptor in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * In long mode and virtual-8086 mode, segment limits are not enforced. Thus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * limit is returned as -1L to imply a limit-less segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * Zero is returned on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct desc_struct desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) unsigned long limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) short sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) sel = get_segment_selector(regs, seg_reg_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (any_64bit_mode(regs) || v8086_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!get_desc(&desc, sel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * If the granularity bit is set, the limit is given in multiples
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * of 4096. This also means that the 12 least significant bits are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * not tested when checking the segment limits. In practice,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * this means that the segment ends in (limit << 12) + 0xfff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) limit = get_desc_limit(&desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (desc.g)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) limit = (limit << 12) + 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * insn_get_code_seg_params() - Obtain code segment parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * Obtain address and operand sizes of the code segment. It is obtained from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * selector contained in the CS register in regs. In protected mode, the default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * address is determined by inspecting the L and D bits of the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * descriptor. In virtual-8086 mode, the default is always two bytes for both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * address and operand sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * An int containing ORed-in default parameters on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int insn_get_code_seg_params(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct desc_struct desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) short sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (v8086_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* Address and operand size are both 16-bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return INSN_CODE_SEG_PARAMS(2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) sel = get_segment_selector(regs, INAT_SEG_REG_CS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (!get_desc(&desc, sel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * The most significant byte of the Type field of the segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * determines whether a segment contains data or code. If this is a data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * segment, return error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!(desc.type & BIT(3)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) switch ((desc.l << 1) | desc.d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case 0: /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * Legacy mode. CS.L=0, CS.D=0. Address and operand size are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * both 16-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return INSN_CODE_SEG_PARAMS(2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case 1: /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * Legacy mode. CS.L=0, CS.D=1. Address and operand size are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * both 32-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return INSN_CODE_SEG_PARAMS(4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) case 2: /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * IA-32e 64-bit mode. CS.L=1, CS.D=0. Address size is 64-bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * operand size is 32-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return INSN_CODE_SEG_PARAMS(4, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case 3: /* Invalid setting. CS.L=1, CS.D=1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * insn_get_modrm_rm_off() - Obtain register in r/m part of the ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * @insn: Instruction containing the ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * The register indicated by the r/m part of the ModRM byte. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * register is obtained as an offset from the base of pt_regs. In specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * cases, the returned value can be -EDOM to indicate that the particular value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * of ModRM does not refer to a register and shall be ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return get_reg_offset(insn, regs, REG_TYPE_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * insn_get_modrm_reg_off() - Obtain register in reg part of the ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * @insn: Instruction containing the ModRM byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * The register indicated by the reg part of the ModRM byte. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * register is obtained as an offset from the base of pt_regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return get_reg_offset(insn, regs, REG_TYPE_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * get_seg_base_limit() - obtain base address and limit of a segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * @insn: Instruction. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @regoff: Operand offset, in pt_regs, used to resolve segment descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * @base: Obtained segment base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * @limit: Obtained segment limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * Obtain the base address and limit of the segment associated with the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * @regoff and, if any or allowed, override prefixes in @insn. This function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * different from insn_get_seg_base() as the latter does not resolve the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * associated with the instruction operand. If a limit is not needed (e.g.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * when running in long mode), @limit can be NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * 0 on success. @base and @limit will contain the base address and of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * resolved segment, respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static int get_seg_base_limit(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) int regoff, unsigned long *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) unsigned long *limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) int seg_reg_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) seg_reg_idx = resolve_seg_reg(insn, regs, regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (seg_reg_idx < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return seg_reg_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) *base = insn_get_seg_base(regs, seg_reg_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (*base == -1L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) *limit = get_seg_limit(regs, seg_reg_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (!(*limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * get_eff_addr_reg() - Obtain effective address from register operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) * @insn: Instruction. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * @regoff: Obtained operand offset, in pt_regs, with the effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * @eff_addr: Obtained effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * Obtain the effective address stored in the register operand as indicated by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * the ModRM byte. This function is to be used only with register addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * (i.e., ModRM.mod is 3). The effective address is saved in @eff_addr. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * register operand, as an offset from the base of pt_regs, is saved in @regoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * such offset can then be used to resolve the segment associated with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * operand. This function can be used with any of the supported address sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * in x86.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * 0 on success. @eff_addr will have the effective address stored in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * operand indicated by ModRM. @regoff will have such operand as an offset from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * the base of pt_regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static int get_eff_addr_reg(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int *regoff, long *eff_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (X86_MODRM_MOD(insn->modrm.value) != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) *regoff = get_reg_offset(insn, regs, REG_TYPE_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (*regoff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Ignore bytes that are outside the address size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (insn->addr_bytes == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) *eff_addr = regs_get_register(regs, *regoff) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) else if (insn->addr_bytes == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) *eff_addr = regs_get_register(regs, *regoff) & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) else /* 64-bit address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) *eff_addr = regs_get_register(regs, *regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * get_eff_addr_modrm() - Obtain referenced effective address via ModRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * @insn: Instruction. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * @regoff: Obtained operand offset, in pt_regs, associated with segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * @eff_addr: Obtained effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Obtain the effective address referenced by the ModRM byte of @insn. After
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * identifying the registers involved in the register-indirect memory reference,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * its value is obtained from the operands in @regs. The computed address is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * stored @eff_addr. Also, the register operand that indicates the associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * segment is stored in @regoff, this parameter can later be used to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * such segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * 0 on success. @eff_addr will have the referenced effective address. @regoff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * will have a register, as an offset from the base of pt_regs, that can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * to resolve the associated segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int *regoff, long *eff_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (insn->addr_bytes != 8 && insn->addr_bytes != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (X86_MODRM_MOD(insn->modrm.value) > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) *regoff = get_reg_offset(insn, regs, REG_TYPE_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * -EDOM means that we must ignore the address_offset. In such a case,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * in 64-bit mode the effective address relative to the rIP of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * following instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (*regoff == -EDOM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (any_64bit_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) tmp = regs->ip + insn->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) } else if (*regoff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) tmp = regs_get_register(regs, *regoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (insn->addr_bytes == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) int addr32 = (int)(tmp & 0xffffffff) + insn->displacement.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) *eff_addr = addr32 & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) *eff_addr = tmp + insn->displacement.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * get_eff_addr_modrm_16() - Obtain referenced effective address via ModRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * @insn: Instruction. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * @regoff: Obtained operand offset, in pt_regs, associated with segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * @eff_addr: Obtained effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * Obtain the 16-bit effective address referenced by the ModRM byte of @insn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * After identifying the registers involved in the register-indirect memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * reference, its value is obtained from the operands in @regs. The computed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * address is stored @eff_addr. Also, the register operand that indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * the associated segment is stored in @regoff, this parameter can later be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * to determine such segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * 0 on success. @eff_addr will have the referenced effective address. @regoff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * will have a register, as an offset from the base of pt_regs, that can be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * to resolve the associated segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int *regoff, short *eff_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) int addr_offset1, addr_offset2, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) short addr1 = 0, addr2 = 0, displacement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (insn->addr_bytes != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (X86_MODRM_MOD(insn->modrm.value) > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ret = get_reg_offset_16(insn, regs, &addr_offset1, &addr_offset2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * Don't fail on invalid offset values. They might be invalid because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * they cannot be used for this particular value of ModRM. Instead, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * them in the computation only if they contain a valid value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (addr_offset1 != -EDOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) addr1 = regs_get_register(regs, addr_offset1) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (addr_offset2 != -EDOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) addr2 = regs_get_register(regs, addr_offset2) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) displacement = insn->displacement.value & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) *eff_addr = addr1 + addr2 + displacement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * The first operand register could indicate to use of either SS or DS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * registers to obtain the segment selector. The second operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * register can only indicate the use of DS. Thus, the first operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * will be used to obtain the segment selector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) *regoff = addr_offset1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) * get_eff_addr_sib() - Obtain referenced effective address via SIB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * @insn: Instruction. Must be valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * @regoff: Obtained operand offset, in pt_regs, associated with segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * @eff_addr: Obtained effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * Obtain the effective address referenced by the SIB byte of @insn. After
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * identifying the registers involved in the indexed, register-indirect memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * reference, its value is obtained from the operands in @regs. The computed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * address is stored @eff_addr. Also, the register operand that indicates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * associated segment is stored in @regoff, this parameter can later be used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * determine such segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * 0 on success. @eff_addr will have the referenced effective address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * @base_offset will have a register, as an offset from the base of pt_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * that can be used to resolve the associated segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * -EINVAL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) static int get_eff_addr_sib(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) int *base_offset, long *eff_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) long base, indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) int indx_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (insn->addr_bytes != 8 && insn->addr_bytes != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (X86_MODRM_MOD(insn->modrm.value) > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) insn_get_sib(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (!insn->sib.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) *base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) indx_offset = get_reg_offset(insn, regs, REG_TYPE_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) * Negative values in the base and index offset means an error when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * decoding the SIB byte. Except -EDOM, which means that the registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * should not be used in the address computation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (*base_offset == -EDOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else if (*base_offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) base = regs_get_register(regs, *base_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (indx_offset == -EDOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) indx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) else if (indx_offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) indx = regs_get_register(regs, indx_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (insn->addr_bytes == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int addr32, base32, idx32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) base32 = base & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) idx32 = indx & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) addr32 = base32 + idx32 * (1 << X86_SIB_SCALE(insn->sib.value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) addr32 += insn->displacement.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) *eff_addr = addr32 & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) *eff_addr = base + indx * (1 << X86_SIB_SCALE(insn->sib.value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) *eff_addr += insn->displacement.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * get_addr_ref_16() - Obtain the 16-bit address referred by instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * @insn: Instruction containing ModRM byte and displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * This function is to be used with 16-bit address encodings. Obtain the memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * address referred by the instruction's ModRM and displacement bytes. Also, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * segment used as base is determined by either any segment override prefixes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * @insn or the default segment of the registers involved in the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * computation. In protected mode, segment limits are enforced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * Linear address referenced by the instruction operands on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * -1L on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static void __user *get_addr_ref_16(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) unsigned long linear_addr = -1L, seg_base, seg_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) int ret, regoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) short eff_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) insn_get_displacement(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (insn->addr_bytes != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (X86_MODRM_MOD(insn->modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) ret = get_eff_addr_reg(insn, regs, ®off, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) eff_addr = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ret = get_eff_addr_modrm_16(insn, regs, ®off, &eff_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * Before computing the linear address, make sure the effective address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * is within the limits of the segment. In virtual-8086 mode, segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * limits are not enforced. In such a case, the segment limit is -1L to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * reflect this fact.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if ((unsigned long)(eff_addr & 0xffff) > seg_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) linear_addr = (unsigned long)(eff_addr & 0xffff) + seg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /* Limit linear address to 20 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (v8086_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) linear_addr &= 0xfffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return (void __user *)linear_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * get_addr_ref_32() - Obtain a 32-bit linear address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * @insn: Instruction with ModRM, SIB bytes and displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * @regs: Register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * This function is to be used with 32-bit address encodings to obtain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * linear memory address referred by the instruction's ModRM, SIB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * displacement bytes and segment base address, as applicable. If in protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * mode, segment limits are enforced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * Linear address referenced by instruction and registers on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * -1L on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) unsigned long linear_addr = -1L, seg_base, seg_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int eff_addr, regoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (insn->addr_bytes != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (X86_MODRM_MOD(insn->modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) ret = get_eff_addr_reg(insn, regs, ®off, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) eff_addr = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (insn->sib.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) ret = get_eff_addr_sib(insn, regs, ®off, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) eff_addr = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ret = get_eff_addr_modrm(insn, regs, ®off, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) eff_addr = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ret = get_seg_base_limit(insn, regs, regoff, &seg_base, &seg_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * In protected mode, before computing the linear address, make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * the effective address is within the limits of the segment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * 32-bit addresses can be used in long and virtual-8086 modes if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * address override prefix is used. In such cases, segment limits are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * not enforced. When in virtual-8086 mode, the segment limit is -1L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * to reflect this situation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * After computed, the effective address is treated as an unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * quantity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * Even though 32-bit address encodings are allowed in virtual-8086
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * mode, the address range is still limited to [0x-0xffff].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (v8086_mode(regs) && (eff_addr & ~0xffff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) * Data type long could be 64 bits in size. Ensure that our 32-bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * effective address is not sign-extended when computing the linear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) linear_addr = (unsigned long)(eff_addr & 0xffffffff) + seg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /* Limit linear address to 20 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (v8086_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) linear_addr &= 0xfffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return (void __user *)linear_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * get_addr_ref_64() - Obtain a 64-bit linear address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * @insn: Instruction struct with ModRM and SIB bytes and displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * This function is to be used with 64-bit address encodings to obtain the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * linear memory address referred by the instruction's ModRM, SIB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * displacement bytes and segment base address, as applicable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) * Linear address referenced by instruction and registers on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) * -1L on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) #ifndef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return (void __user *)-1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static void __user *get_addr_ref_64(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) unsigned long linear_addr = -1L, seg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) int regoff, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) long eff_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (insn->addr_bytes != 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (X86_MODRM_MOD(insn->modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) ret = get_eff_addr_reg(insn, regs, ®off, &eff_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (insn->sib.nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ret = get_eff_addr_sib(insn, regs, ®off, &eff_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ret = get_eff_addr_modrm(insn, regs, ®off, &eff_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ret = get_seg_base_limit(insn, regs, regoff, &seg_base, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) linear_addr = (unsigned long)eff_addr + seg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return (void __user *)linear_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) #endif /* CONFIG_X86_64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) * insn_get_addr_ref() - Obtain the linear address referred by instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) * @insn: Instruction structure containing ModRM byte and displacement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) * Obtain the linear address referred by the instruction's ModRM, SIB and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * displacement bytes, and segment base, as applicable. In protected mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) * segment limits are enforced.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) * Linear address referenced by instruction and registers on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * -1L on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (!insn || !regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return (void __user *)-1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) switch (insn->addr_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return get_addr_ref_16(insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return get_addr_ref_32(insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return get_addr_ref_64(insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return (void __user *)-1L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) unsigned long insn_get_effective_ip(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) unsigned long seg_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * If not in user-space long mode, a custom code segment could be in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * use. This is true in protected mode (if the process defined a local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * descriptor table), or virtual-8086 mode. In most of the cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * seg_base will be zero as in USER_CS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (!user_64bit_mode(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) seg_base = insn_get_seg_base(regs, INAT_SEG_REG_CS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (seg_base == -1L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) return seg_base + regs->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * insn_fetch_from_user() - Copy instruction bytes from user-space memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * @buf: Array to store the fetched instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * Gets the linear address of the instruction and copies the instruction bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) * to the buf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * Number of instruction bytes copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * 0 if nothing was copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) unsigned long ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) int not_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ip = insn_get_effective_ip(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (!ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) not_copied = copy_from_user(buf, (void __user *)ip, MAX_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return MAX_INSN_SIZE - not_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * insn_fetch_from_user_inatomic() - Copy instruction bytes from user-space memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * while in atomic code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * @buf: Array to store the fetched instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * Gets the linear address of the instruction and copies the instruction bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * to the buf. This function must be used in atomic context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * Number of instruction bytes copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) * 0 if nothing was copied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) int insn_fetch_from_user_inatomic(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) unsigned long ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) int not_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ip = insn_get_effective_ip(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) not_copied = __copy_from_user_inatomic(buf, (void __user *)ip, MAX_INSN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return MAX_INSN_SIZE - not_copied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * insn_decode() - Decode an instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * @insn: Structure to store decoded instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * @regs: Structure with register values as seen when entering kernel mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * @buf: Buffer containing the instruction bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * @buf_size: Number of instruction bytes available in buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * Decodes the instruction provided in buf and stores the decoding results in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * insn. Also determines the correct address and operand sizes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * True if instruction was decoded, False otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) bool insn_decode(struct insn *insn, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) unsigned char buf[MAX_INSN_SIZE], int buf_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) int seg_defs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) insn_init(insn, buf, buf_size, user_64bit_mode(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * Override the default operand and address sizes with what is specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * in the code segment descriptor. The instruction decoder only sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * the address size it to either 4 or 8 address bytes and does nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * for the operand bytes. This OK for most of the cases, but we could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * have special cases where, for instance, a 16-bit code segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * descriptor is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * If there is an address override prefix, the instruction decoder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * correctly updates these values, even for 16-bit defaults.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) seg_defs = insn_get_code_seg_params(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (seg_defs == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) insn->addr_bytes = INSN_CODE_SEG_ADDR_SZ(seg_defs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) insn->opnd_bytes = INSN_CODE_SEG_OPND_SZ(seg_defs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) insn_get_length(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (buf_size < insn->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }