int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs);
 unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
 int insn_get_code_seg_params(struct pt_regs *regs);
+int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip);
 int insn_fetch_from_user(struct pt_regs *regs,
                         unsigned char buf[MAX_INSN_SIZE]);
 int insn_fetch_from_user_inatomic(struct pt_regs *regs,
 
        frame->ret_addr = (unsigned long) ret_from_fork;
        p->thread.sp = (unsigned long) fork_frame;
        p->thread.io_bitmap = NULL;
+       p->thread.iopl_warn = 0;
        memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
 
 #ifdef CONFIG_X86_64
 
 
 #define GPFSTR "general protection fault"
 
+static bool fixup_iopl_exception(struct pt_regs *regs)
+{
+       struct thread_struct *t = ¤t->thread;
+       unsigned char byte;
+       unsigned long ip;
+
+       if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3)
+               return false;
+
+       if (insn_get_effective_ip(regs, &ip))
+               return false;
+
+       if (get_user(byte, (const char __user *)ip))
+               return false;
+
+       if (byte != 0xfa && byte != 0xfb)
+               return false;
+
+       if (!t->iopl_warn && printk_ratelimit()) {
+               pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx",
+                      current->comm, task_pid_nr(current), ip);
+               print_vma_addr(KERN_CONT " in ", ip);
+               pr_cont("\n");
+               t->iopl_warn = 1;
+       }
+
+       regs->ip += 1;
+       return true;
+}
+
 DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 {
        char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
        tsk = current;
 
        if (user_mode(regs)) {
+               if (fixup_iopl_exception(regs))
+                       goto exit;
+
                tsk->thread.error_code = error_code;
                tsk->thread.trap_nr = X86_TRAP_GP;
 
 
        }
 }
 
-static int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip)
+int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip)
 {
        unsigned long seg_base = 0;