return flags;
 }
 
-extern inline void native_restore_fl(unsigned long flags);
-extern inline void native_restore_fl(unsigned long flags)
-{
-       asm volatile("push %0 ; popf"
-                    : /* no output */
-                    :"g" (flags)
-                    :"memory", "cc");
-}
-
 static __always_inline void native_irq_disable(void)
 {
        asm volatile("cli": : :"memory");
        return native_save_fl();
 }
 
-static __always_inline void arch_local_irq_restore(unsigned long flags)
-{
-       native_restore_fl(flags);
-}
-
 static __always_inline void arch_local_irq_disable(void)
 {
        native_irq_disable();
 
        return arch_irqs_disabled_flags(flags);
 }
+
+static __always_inline void arch_local_irq_restore(unsigned long flags)
+{
+       if (!arch_irqs_disabled_flags(flags))
+               arch_local_irq_enable();
+}
 #else
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_XEN_PV
 
        return PVOP_CALLEE0(unsigned long, irq.save_fl);
 }
 
-static inline notrace void arch_local_irq_restore(unsigned long f)
-{
-       PVOP_VCALLEE1(irq.restore_fl, f);
-}
-
 static inline notrace void arch_local_irq_disable(void)
 {
        PVOP_VCALLEE0(irq.irq_disable);
 
 struct pv_irq_ops {
 #ifdef CONFIG_PARAVIRT_XXL
        /*
-        * Get/set interrupt state.  save_fl and restore_fl are only
-        * expected to use X86_EFLAGS_IF; all other bits
-        * returned from save_fl are undefined, and may be ignored by
-        * restore_fl.
+        * Get/set interrupt state.  save_fl is expected to use X86_EFLAGS_IF;
+        * all other bits returned from save_fl are undefined.
         *
         * NOTE: These functions callers expect the callee to preserve
         * more registers than the standard C calling convention.
         */
        struct paravirt_callee_save save_fl;
-       struct paravirt_callee_save restore_fl;
        struct paravirt_callee_save irq_disable;
        struct paravirt_callee_save irq_enable;
 
 
        ret
 SYM_FUNC_END(native_save_fl)
 EXPORT_SYMBOL(native_save_fl)
-
-/*
- * void native_restore_fl(unsigned long flags)
- * %eax/%rdi: flags
- */
-SYM_FUNC_START(native_restore_fl)
-       push %_ASM_ARG1
-       popf
-       ret
-SYM_FUNC_END(native_restore_fl)
-EXPORT_SYMBOL(native_restore_fl)
 
 
        /* Irq ops. */
        .irq.save_fl            = __PV_IS_CALLEE_SAVE(native_save_fl),
-       .irq.restore_fl         = __PV_IS_CALLEE_SAVE(native_restore_fl),
        .irq.irq_disable        = __PV_IS_CALLEE_SAVE(native_irq_disable),
        .irq.irq_enable         = __PV_IS_CALLEE_SAVE(native_irq_enable),
        .irq.safe_halt          = native_safe_halt,
 
        const unsigned char     mmu_read_cr2[3];
        const unsigned char     mmu_read_cr3[3];
        const unsigned char     mmu_write_cr3[3];
-       const unsigned char     irq_restore_fl[2];
        const unsigned char     cpu_wbinvd[2];
        const unsigned char     mov64[3];
 };
        .mmu_read_cr2           = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax
        .mmu_read_cr3           = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax
        .mmu_write_cr3          = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3
-       .irq_restore_fl         = { 0x57, 0x9d },       // push %rdi; popfq
        .cpu_wbinvd             = { 0x0f, 0x09 },       // wbinvd
        .mov64                  = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax
 };
        switch (type) {
 
 #ifdef CONFIG_PARAVIRT_XXL
-       PATCH_CASE(irq, restore_fl, xxl, insn_buff, len);
        PATCH_CASE(irq, save_fl, xxl, insn_buff, len);
        PATCH_CASE(irq, irq_enable, xxl, insn_buff, len);
        PATCH_CASE(irq, irq_disable, xxl, insn_buff, len);
 
         */
        if (xen_have_vcpu_info_placement) {
                pv_ops.irq.save_fl = __PV_IS_CALLEE_SAVE(xen_save_fl_direct);
-               pv_ops.irq.restore_fl =
-                       __PV_IS_CALLEE_SAVE(xen_restore_fl_direct);
                pv_ops.irq.irq_disable =
                        __PV_IS_CALLEE_SAVE(xen_irq_disable_direct);
                pv_ops.irq.irq_enable =
 
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
 
-__visible void xen_restore_fl(unsigned long flags)
-{
-       struct vcpu_info *vcpu;
-
-       /* convert from IF type flag */
-       flags = !(flags & X86_EFLAGS_IF);
-
-       /* See xen_irq_enable() for why preemption must be disabled. */
-       preempt_disable();
-       vcpu = this_cpu_read(xen_vcpu);
-       vcpu->evtchn_upcall_mask = flags;
-
-       if (flags == 0) {
-               barrier(); /* unmask then check (avoid races) */
-               if (unlikely(vcpu->evtchn_upcall_pending))
-                       xen_force_evtchn_callback();
-               preempt_enable();
-       } else
-               preempt_enable_no_resched();
-}
-PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl);
-
 asmlinkage __visible void xen_irq_disable(void)
 {
        /* There's a one instruction preempt window here.  We need to
 
 static const struct pv_irq_ops xen_irq_ops __initconst = {
        .save_fl = PV_CALLEE_SAVE(xen_save_fl),
-       .restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
        .irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
        .irq_enable = PV_CALLEE_SAVE(xen_irq_enable),
 
 
        ret
 SYM_FUNC_END(xen_save_fl_direct)
 
-
-/*
- * In principle the caller should be passing us a value return from
- * xen_save_fl_direct, but for robustness sake we test only the
- * X86_EFLAGS_IF flag rather than the whole byte. After setting the
- * interrupt mask state, it checks for unmasked pending events and
- * enters the hypervisor to get them delivered if so.
- */
-SYM_FUNC_START(xen_restore_fl_direct)
-       FRAME_BEGIN
-       testw $X86_EFLAGS_IF, %di
-       setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
-       /*
-        * Preempt here doesn't matter because that will deal with any
-        * pending interrupts.  The pending check may end up being run
-        * on the wrong CPU, but that doesn't hurt.
-        */
-
-       /* check for unmasked and pending */
-       cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
-       jnz 1f
-       call check_events
-1:
-       FRAME_END
-       ret
-SYM_FUNC_END(xen_restore_fl_direct)
-
-
 /*
  * Force an event check by making a hypercall, but preserve regs
  * before making the call.
 
 __visible void xen_irq_enable_direct(void);
 __visible void xen_irq_disable_direct(void);
 __visible unsigned long xen_save_fl_direct(void);
-__visible void xen_restore_fl_direct(unsigned long);
 
 __visible unsigned long xen_read_cr2(void);
 __visible unsigned long xen_read_cr2_direct(void);