Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * umip.c Emulation for instruction protected by the User-Mode Instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Prevention feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2017, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <asm/umip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/insn-eval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #undef pr_fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define pr_fmt(fmt) "umip: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /** DOC: Emulation for User-Mode Instruction Prevention (UMIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * User-Mode Instruction Prevention is a security feature present in recent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * x86 processors that, when enabled, prevents a group of instructions (SGDT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * SIDT, SLDT, SMSW and STR) from being run in user mode by issuing a general
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * protection fault if the instruction is executed with CPL > 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * Rather than relaying to the user space the general protection fault caused by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * the UMIP-protected instructions (in the form of a SIGSEGV signal), it can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * trapped and emulate the result of such instructions to provide dummy values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * This allows to both conserve the current kernel behavior and not reveal the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * system resources that UMIP intends to protect (i.e., the locations of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * global descriptor and interrupt descriptor tables, the segment selectors of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * the local descriptor table, the value of the task state register and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * contents of the CR0 register).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * This emulation is needed because certain applications (e.g., WineHQ and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * DOSEMU2) rely on this subset of instructions to function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * The instructions protected by UMIP can be split in two groups. Those which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * return a kernel memory address (SGDT and SIDT) and those which return a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * value (SLDT, STR and SMSW).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * For the instructions that return a kernel memory address, applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * such as WineHQ rely on the result being located in the kernel memory space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * not the actual location of the table. The result is emulated as a hard-coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * value that, lies close to the top of the kernel memory. The limit for the GDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * and the IDT are set to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * The instruction SMSW is emulated to return the value that the register CR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * has at boot time as set in the head_32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * SLDT and STR are emulated to return the values that the kernel programmatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * assigns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * - SLDT returns (GDT_ENTRY_LDT * 8) if an LDT has been set, 0 if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * - STR returns (GDT_ENTRY_TSS * 8).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  * Emulation is provided for both 32-bit and 64-bit processes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * Care is taken to appropriately emulate the results when segmentation is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * used. That is, rather than relying on USER_DS and USER_CS, the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * insn_get_addr_ref() inspects the segment descriptor pointed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * registers in pt_regs. This ensures that we correctly obtain the segment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * base address and the address and operand sizes even if the user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * application uses a local descriptor table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define UMIP_DUMMY_GDT_BASE 0xfffffffffffe0000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define UMIP_DUMMY_IDT_BASE 0xffffffffffff0000ULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * The SGDT and SIDT instructions store the contents of the global descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * table and interrupt table registers, respectively. The destination is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * memory operand of X+2 bytes. X bytes are used to store the base address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * the table and 2 bytes are used to store the limit. In 32-bit processes X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * has a value of 4, in 64-bit processes X has a value of 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define UMIP_GDT_IDT_BASE_SIZE_64BIT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define UMIP_GDT_IDT_BASE_SIZE_32BIT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define UMIP_GDT_IDT_LIMIT_SIZE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define	UMIP_INST_SGDT	0	/* 0F 01 /0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define	UMIP_INST_SIDT	1	/* 0F 01 /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define	UMIP_INST_SMSW	2	/* 0F 01 /4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define	UMIP_INST_SLDT  3       /* 0F 00 /0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define	UMIP_INST_STR   4       /* 0F 00 /1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static const char * const umip_insns[5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	[UMIP_INST_SGDT] = "SGDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	[UMIP_INST_SIDT] = "SIDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	[UMIP_INST_SMSW] = "SMSW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	[UMIP_INST_SLDT] = "SLDT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	[UMIP_INST_STR] = "STR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define umip_pr_err(regs, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	umip_printk(regs, KERN_ERR, fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define umip_pr_warn(regs, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	umip_printk(regs, KERN_WARNING, fmt,  ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * umip_printk() - Print a rate-limited message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * @regs:	Register set with the context in which the warning is printed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @log_level:	Kernel log level to print the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * @fmt:	The text string to print
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * Print the text contained in @fmt. The print rate is limited to bursts of 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * messages every two minutes. The purpose of this customized version of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * printk() is to print messages when user space processes use any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * UMIP-protected instructions. Thus, the printed text is prepended with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * task name and process ID number of the current task as well as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * instruction and stack pointers in @regs as seen when entering kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void umip_printk(const struct pt_regs *regs, const char *log_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		 const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/* Bursts of 5 messages every two minutes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	static DEFINE_RATELIMIT_STATE(ratelimit, 2 * 60 * HZ, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (!__ratelimit(&ratelimit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	printk("%s" pr_fmt("%s[%d] ip:%lx sp:%lx: %pV"), log_level, tsk->comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	       task_pid_nr(tsk), regs->ip, regs->sp, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * identify_insn() - Identify a UMIP-protected instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * @insn:	Instruction structure with opcode and ModRM byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * From the opcode and ModRM.reg in @insn identify, if any, a UMIP-protected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * instruction that can be emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * On success, a constant identifying a specific UMIP-protected instruction that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * can be emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * -EINVAL on error or when not an UMIP-protected instruction that can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * emulated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int identify_insn(struct insn *insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	/* By getting modrm we also get the opcode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	insn_get_modrm(insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (!insn->modrm.nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/* All the instructions of interest start with 0x0f. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (insn->opcode.bytes[0] != 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (insn->opcode.bytes[1] == 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		switch (X86_MODRM_REG(insn->modrm.value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			return UMIP_INST_SGDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			return UMIP_INST_SIDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			return UMIP_INST_SMSW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	} else if (insn->opcode.bytes[1] == 0x0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		if (X86_MODRM_REG(insn->modrm.value) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			return UMIP_INST_SLDT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		else if (X86_MODRM_REG(insn->modrm.value) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			return UMIP_INST_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * emulate_umip_insn() - Emulate UMIP instructions and return dummy values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * @insn:	Instruction structure with operands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  * @umip_inst:	A constant indicating the instruction to emulate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * @data:	Buffer into which the dummy result is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * @data_size:	Size of the emulated result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * @x86_64:	true if process is 64-bit, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * Emulate an instruction protected by UMIP and provide a dummy result. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * result of the emulation is saved in @data. The size of the results depends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  * on both the instruction and type of operand (register vs memory address).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * The size of the result is updated in @data_size. Caller is responsible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * of providing a @data buffer of at least UMIP_GDT_IDT_BASE_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * UMIP_GDT_IDT_LIMIT_SIZE bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * 0 on success, -EINVAL on error while emulating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int emulate_umip_insn(struct insn *insn, int umip_inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			     unsigned char *data, int *data_size, bool x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (!data || !data_size || !insn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	 * These two instructions return the base address and limit of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	 * global and interrupt descriptor table, respectively. According to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	 * Intel Software Development manual, the base address can be 24-bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	 * 32-bit or 64-bit. Limit is always 16-bit. If the operand size is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	 * 16-bit, the returned value of the base address is supposed to be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	 * zero-extended 24-byte number. However, it seems that a 32-byte number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	 * is always returned irrespective of the operand size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (umip_inst == UMIP_INST_SGDT || umip_inst == UMIP_INST_SIDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		u64 dummy_base_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		u16 dummy_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		/* SGDT and SIDT do not use registers operands. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (X86_MODRM_MOD(insn->modrm.value) == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (umip_inst == UMIP_INST_SGDT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			dummy_base_addr = UMIP_DUMMY_GDT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			dummy_base_addr = UMIP_DUMMY_IDT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		 * 64-bit processes use the entire dummy base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		 * 32-bit processes use the lower 32 bits of the base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		 * dummy_base_addr is always 64 bits, but we memcpy the correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		 * number of bytes from it to the destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		if (x86_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			*data_size = UMIP_GDT_IDT_BASE_SIZE_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			*data_size = UMIP_GDT_IDT_BASE_SIZE_32BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		memcpy(data + 2, &dummy_base_addr, *data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		*data_size += UMIP_GDT_IDT_LIMIT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		memcpy(data, &dummy_limit, UMIP_GDT_IDT_LIMIT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	} else if (umip_inst == UMIP_INST_SMSW || umip_inst == UMIP_INST_SLDT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		   umip_inst == UMIP_INST_STR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		unsigned long dummy_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (umip_inst == UMIP_INST_SMSW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			dummy_value = CR0_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		} else if (umip_inst == UMIP_INST_STR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			dummy_value = GDT_ENTRY_TSS * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		} else if (umip_inst == UMIP_INST_SLDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #ifdef CONFIG_MODIFY_LDT_SYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			down_read(&current->mm->context.ldt_usr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			if (current->mm->context.ldt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 				dummy_value = GDT_ENTRY_LDT * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 				dummy_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			up_read(&current->mm->context.ldt_usr_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			dummy_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		 * For these 3 instructions, the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		 * of bytes to be copied in the result buffer is determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		 * by whether the operand is a register or a memory location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		 * If operand is a register, return as many bytes as the operand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		 * size. If operand is memory, return only the two least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		 * siginificant bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		if (X86_MODRM_MOD(insn->modrm.value) == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			*data_size = insn->opnd_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			*data_size = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		memcpy(data, &dummy_value, *data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  * force_sig_info_umip_fault() - Force a SIGSEGV with SEGV_MAPERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * @addr:	Address that caused the signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * @regs:	Register set containing the instruction pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * Force a SIGSEGV signal with SEGV_MAPERR as the error code. This function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * intended to be used to provide a segmentation fault when the result of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * UMIP emulation could not be copied to the user space memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * Returns: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct task_struct *tsk = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	tsk->thread.cr2		= (unsigned long)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	tsk->thread.error_code	= X86_PF_USER | X86_PF_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	tsk->thread.trap_nr	= X86_TRAP_PF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	force_sig_fault(SIGSEGV, SEGV_MAPERR, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	umip_pr_err(regs, "segfault in emulation. error%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		    X86_PF_USER | X86_PF_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)  * fixup_umip_exception() - Fixup a general protection fault caused by UMIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)  * @regs:	Registers as saved when entering the #GP handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  * The instructions SGDT, SIDT, STR, SMSW and SLDT cause a general protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * fault if executed with CPL > 0 (i.e., from user space). This function fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * the exception up and provides dummy results for SGDT, SIDT and SMSW; STR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  * and SLDT are not fixed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * If operands are memory addresses, results are copied to user-space memory as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * indicated by the instruction pointed by eIP using the registers indicated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  * the instruction operands. If operands are registers, results are copied into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)  * the context that was saved when entering kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)  * True if emulation was successful; false if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bool fixup_umip_exception(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int nr_copied, reg_offset, dummy_data_size, umip_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	/* 10 bytes is the maximum size of the result of UMIP instructions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	unsigned char dummy_data[10] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	unsigned char buf[MAX_INSN_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	unsigned long *reg_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	void __user *uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	struct insn insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (!regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	nr_copied = insn_fetch_from_user(regs, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	 * The insn_fetch_from_user above could have failed if user code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	 * is protected by a memory protection key. Give up on emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	 * in such a case.  Should we issue a page fault?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (!nr_copied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (!insn_decode(&insn, regs, buf, nr_copied))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	umip_inst = identify_insn(&insn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (umip_inst < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	umip_pr_warn(regs, "%s instruction cannot be used by applications.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			umip_insns[umip_inst]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	umip_pr_warn(regs, "For now, expensive software emulation returns the result.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (emulate_umip_insn(&insn, umip_inst, dummy_data, &dummy_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			      user_64bit_mode(regs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	 * If operand is a register, write result to the copy of the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	 * value that was pushed to the stack when entering into kernel mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	 * Upon exit, the value we write will be restored to the actual hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	 * register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (X86_MODRM_MOD(insn.modrm.value) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		reg_offset = insn_get_modrm_rm_off(&insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		 * Negative values are usually errors. In memory addressing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		 * the exception is -EDOM. Since we expect a register operand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		 * all negative values are errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		if (reg_offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		reg_addr = (unsigned long *)((unsigned long)regs + reg_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		memcpy(reg_addr, dummy_data, dummy_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		uaddr = insn_get_addr_ref(&insn, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		if ((unsigned long)uaddr == -1L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		nr_copied = copy_to_user(uaddr, dummy_data, dummy_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (nr_copied  > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			 * If copy fails, send a signal and tell caller that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			 * fault was fixed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			force_sig_info_umip_fault(uaddr, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	/* increase IP to let the program keep going */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	regs->ip += insn.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }