diff options
Diffstat (limited to 'arch/x86/lib/insn-eval.c')
| -rw-r--r-- | arch/x86/lib/insn-eval.c | 26 | 
1 files changed, 15 insertions, 11 deletions
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c index 306c3a0902ba..31600d851fd8 100644 --- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -155,7 +155,7 @@ static bool check_seg_overrides(struct insn *insn, int regoff)   */  static int resolve_default_seg(struct insn *insn, struct pt_regs *regs, int off)  { -	if (user_64bit_mode(regs)) +	if (any_64bit_mode(regs))  		return INAT_SEG_REG_IGNORE;  	/*  	 * Resolve the default segment register as described in Section 3.7.4 @@ -266,7 +266,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)  	 * which may be invalid at this point.  	 */  	if (regoff == offsetof(struct pt_regs, ip)) { -		if (user_64bit_mode(regs)) +		if (any_64bit_mode(regs))  			return INAT_SEG_REG_IGNORE;  		else  			return INAT_SEG_REG_CS; @@ -289,7 +289,7 @@ static int resolve_seg_reg(struct insn *insn, struct pt_regs *regs, int regoff)  	 * In long mode, segment override prefixes are ignored, except for  	 * overrides for FS and GS.  	 */ -	if (user_64bit_mode(regs)) { +	if (any_64bit_mode(regs)) {  		if (idx != INAT_SEG_REG_FS &&  		    idx != INAT_SEG_REG_GS)  			idx = INAT_SEG_REG_IGNORE; @@ -646,23 +646,27 @@ unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx)  		 */  		return (unsigned long)(sel << 4); -	if (user_64bit_mode(regs)) { +	if (any_64bit_mode(regs)) {  		/*  		 * Only FS or GS will have a base address, the rest of  		 * the segments' bases are forced to 0.  		 */  		unsigned long base; -		if (seg_reg_idx == INAT_SEG_REG_FS) +		if (seg_reg_idx == INAT_SEG_REG_FS) {  			rdmsrl(MSR_FS_BASE, base); -		else if (seg_reg_idx == INAT_SEG_REG_GS) +		} else if (seg_reg_idx == INAT_SEG_REG_GS) {  			/*  			 * swapgs was called at the kernel entry point. Thus,  			 * MSR_KERNEL_GS_BASE will have the user-space GS base.  			 */ -			rdmsrl(MSR_KERNEL_GS_BASE, base); -		else +			if (user_mode(regs)) +				rdmsrl(MSR_KERNEL_GS_BASE, base); +			else +				rdmsrl(MSR_GS_BASE, base); +		} else {  			base = 0; +		}  		return base;  	} @@ -703,7 +707,7 @@ static unsigned long get_seg_limit(struct pt_regs *regs, int seg_reg_idx)  	if (sel < 0)  		return 0; -	if (user_64bit_mode(regs) || v8086_mode(regs)) +	if (any_64bit_mode(regs) || v8086_mode(regs))  		return -1L;  	if (!sel) @@ -948,7 +952,7 @@ static int get_eff_addr_modrm(struct insn *insn, struct pt_regs *regs,  	 * following instruction.  	 */  	if (*regoff == -EDOM) { -		if (user_64bit_mode(regs)) +		if (any_64bit_mode(regs))  			tmp = regs->ip + insn->length;  		else  			tmp = 0; @@ -1250,7 +1254,7 @@ static void __user *get_addr_ref_32(struct insn *insn, struct pt_regs *regs)  	 * After computed, the effective address is treated as an unsigned  	 * quantity.  	 */ -	if (!user_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit)) +	if (!any_64bit_mode(regs) && ((unsigned int)eff_addr > seg_limit))  		goto out;  	/*  |