Module: xenomai-3
Branch: wip/prioceil
Commit: d05500a29b6b8613ad54b95a1ed46138d70df369
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=d05500a29b6b8613ad54b95a1ed46138d70df369

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Mar 13 12:12:27 2016 +0100

cobalt/x86: upgrade I-pipe support

---

 ...-x86-6.patch => ipipe-core-3.10.32-x86-7.patch} |  135 ++++---
 ...x86-9.patch => ipipe-core-3.14.44-x86-11.patch} |  383 ++++++++++++--------
 ...-x86-3.patch => ipipe-core-3.18.20-x86-5.patch} |  230 +++++++-----
 ...8-x86-1.patch => ipipe-core-4.1.18-x86-2.patch} |   15 +-
 4 files changed, 467 insertions(+), 296 deletions(-)

diff --git a/kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-6.patch 
b/kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-7.patch
similarity index 99%
rename from kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-6.patch
rename to kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-7.patch
index 04b1d47..2702f29 100644
--- a/kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-6.patch
+++ b/kernel/cobalt/arch/x86/patches/ipipe-core-3.10.32-x86-7.patch
@@ -1,5 +1,5 @@
 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index fe120da..6882e5c 100644
+index fe120da..19c951e 100644
 --- a/arch/x86/Kconfig
 +++ b/arch/x86/Kconfig
 @@ -9,6 +9,7 @@ config 64BIT
@@ -10,17 +10,18 @@ index fe120da..6882e5c 100644
        select CLKSRC_I8253
        select HAVE_UID16
  
-@@ -20,6 +21,9 @@ config X86_64
+@@ -20,6 +21,10 @@ config X86_64
  ### Arch settings
  config X86
        def_bool y
 +      select IPIPE_HAVE_HOSTRT if IPIPE
 +      select IPIPE_HAVE_VM_NOTIFIER if IPIPE
 +      select IPIPE_HAVE_SAFE_THREAD_INFO if X86_64
++      select IPIPE_WANT_PTE_PINNING if IPIPE
        select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
        select HAVE_AOUT if X86_32
        select HAVE_UNSTABLE_SCHED_CLOCK
-@@ -106,7 +110,7 @@ config X86
+@@ -106,7 +111,7 @@ config X86
        select GENERIC_CLOCKEVENTS
        select ARCH_CLOCKSOURCE_DATA if X86_64
        select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && 
X86_LOCAL_APIC)
@@ -29,7 +30,7 @@ index fe120da..6882e5c 100644
        select KTIME_SCALAR if X86_32
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
-@@ -605,6 +609,7 @@ if HYPERVISOR_GUEST
+@@ -605,6 +610,7 @@ if HYPERVISOR_GUEST
  
  config PARAVIRT
        bool "Enable paravirtualization code"
@@ -37,7 +38,7 @@ index fe120da..6882e5c 100644
        ---help---
          This changes the kernel so it can modify itself when it is run
          under a hypervisor, potentially improving performance significantly
-@@ -837,6 +842,8 @@ config SCHED_MC
+@@ -837,6 +843,8 @@ config SCHED_MC
  
  source "kernel/Kconfig.preempt"
  
@@ -276,7 +277,7 @@ index 615fa90..e0a62ab 100644
  extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
 diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h
 new file mode 100644
-index 0000000..9e2c783
+index 0000000..6e490b5
 --- /dev/null
 +++ b/arch/x86/include/asm/ipipe.h
 @@ -0,0 +1,104 @@
@@ -306,7 +307,7 @@ index 0000000..9e2c783
 +
 +#ifdef CONFIG_IPIPE
 +
-+#define IPIPE_CORE_RELEASE    6
++#define IPIPE_CORE_RELEASE    7
 +
 +struct ipipe_domain;
 +
@@ -2058,7 +2059,7 @@ index deeb48d..4c1be96 100644
  #else /* CONFIG_X86_64 */
  
 diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c 
b/arch/x86/kernel/cpu/mtrr/cyrix.c
-index 68a3343..057710f 100644
+index 68a3343..057710f3 100644
 --- a/arch/x86/kernel/cpu/mtrr/cyrix.c
 +++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
 @@ -18,7 +18,7 @@ cyrix_get_arr(unsigned int reg, unsigned long *base,
@@ -4710,7 +4711,7 @@ index 4f74d94..022d754 100644
  
        do {
 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
-index c1e9e4c..0d05419 100644
+index c1e9e4c..ee21fbd 100644
 --- a/arch/x86/mm/fault.c
 +++ b/arch/x86/mm/fault.c
 @@ -355,9 +355,9 @@ void vmalloc_sync_all(void)
@@ -4764,7 +4765,7 @@ index c1e9e4c..0d05419 100644
  }
 +
 +#ifdef CONFIG_IPIPE
-+void __ipipe_pin_range_globally(unsigned long start, unsigned long end)
++void __ipipe_pin_mapping_globally(unsigned long start, unsigned long end)
 +{
 +#ifdef CONFIG_X86_32
 +      unsigned long next, addr = start;
@@ -5554,10 +5555,10 @@ index e6bb36a..898a91a 100644
  
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..525f3cf
+index 0000000..4ef7e3d
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,443 @@
+@@ -0,0 +1,449 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -5964,6 +5965,12 @@ index 0000000..525f3cf
 +#define __ipipe_uaccess_might_fault() might_fault()
 +#endif
 +
++#ifdef CONFIG_IPIPE_TRACE
++void __ipipe_tracer_hrclock_initialized(void);
++#else /* !CONFIG_IPIPE_TRACE */
++#define __ipipe_tracer_hrclock_initialized()  do { } while(0)
++#endif /* !CONFIG_IPIPE_TRACE */
++
 +#include <linux/ipipe_compat.h>
 +
 +#else /* !CONFIG_IPIPE */
@@ -6003,10 +6010,10 @@ index 0000000..525f3cf
 +#endif        /* !__LINUX_IPIPE_H */
 diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
 new file mode 100644
-index 0000000..fc88b2e
+index 0000000..c8fed98
 --- /dev/null
 +++ b/include/linux/ipipe_base.h
-@@ -0,0 +1,392 @@
+@@ -0,0 +1,394 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_base.h
 + *
@@ -6189,9 +6196,6 @@ index 0000000..fc88b2e
 +
 +void __ipipe_flush_printk(unsigned int irq, void *cookie);
 +
-+void __ipipe_pin_range_globally(unsigned long start,
-+                              unsigned long end);
-+
 +#define hard_preempt_disable()                                \
 +      ({                                              \
 +              unsigned long __flags__;                \
@@ -6359,10 +6363,6 @@ index 0000000..fc88b2e
 +
 +static inline void __ipipe_clear_taskflags(struct task_struct *p) { }
 +
-+static inline void __ipipe_pin_range_globally(unsigned long start,
-+                                            unsigned long end)
-+{ }
-+
 +#define hard_preempt_disable()                ({ preempt_disable(); 0; })
 +#define hard_preempt_enable(flags)    ({ preempt_enable(); (void)(flags); })
 +
@@ -6389,6 +6389,15 @@ index 0000000..fc88b2e
 +
 +#endif        /* !CONFIG_IPIPE */
 +
++#ifdef CONFIG_IPIPE_WANT_PTE_PINNING
++void __ipipe_pin_mapping_globally(unsigned long start,
++                                unsigned long end);
++#else
++static inline void __ipipe_pin_mapping_globally(unsigned long start,
++                                              unsigned long end)
++{ }
++#endif
++
 +static inline void ipipe_preempt_root_only(void)
 +{
 +#if defined(CONFIG_IPIPE_DEBUG_CONTEXT) && \
@@ -8540,10 +8549,10 @@ index ff7be9d..1e80528 100644
        trace_task_newtask(p, clone_flags);
 diff --git a/kernel/ipipe/Kconfig b/kernel/ipipe/Kconfig
 new file mode 100644
-index 0000000..da17b04
+index 0000000..218f51da
 --- /dev/null
 +++ b/kernel/ipipe/Kconfig
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,65 @@
 +config IPIPE
 +      bool "Interrupt pipeline"
 +      default y
@@ -8564,6 +8573,9 @@ index 0000000..da17b04
 +config IPIPE_WANT_CLOCKSOURCE
 +       bool
 +
++config IPIPE_WANT_PTE_PINNING
++       bool
++
 +config IPIPE_CORE_APIREV
 +       int
 +       depends on IPIPE
@@ -11339,10 +11351,10 @@ index 0000000..0c9b908
 +#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..5cce0bc
+index 0000000..8388671
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
-@@ -0,0 +1,1447 @@
+@@ -0,0 +1,1468 @@
 +/* -*- linux-c -*-
 + * kernel/ipipe/tracer.c
 + *
@@ -12090,6 +12102,9 @@ index 0000000..5cce0bc
 +      unsigned long long abs_tsc;
 +      long us;
 +
++      if (!__ipipe_hrclock_ok())
++              return 0;
++
 +      /* ipipe_tsc2us works on unsigned => handle sign separately */
 +      abs_tsc = (tsc >= 0) ? tsc : -tsc;
 +      us = ipipe_tsc2us(abs_tsc);
@@ -12292,6 +12307,11 @@ index 0000000..5cce0bc
 +
 +              __ipipe_global_path_unlock(flags);
 +
++              if (!__ipipe_hrclock_ok()) {
++                      seq_printf(m, "No hrclock available, dumping traces 
disabled\n");
++                      return NULL;
++              }
++
 +              /* does this path actually contain data? */
 +              if (print_path->end == print_path->begin)
 +                      return NULL;
@@ -12462,6 +12482,11 @@ index 0000000..5cce0bc
 +              if (!print_path)
 +                      return NULL;
 +
++              if (!__ipipe_hrclock_ok()) {
++                      seq_printf(m, "No hrclock available, dumping traces 
disabled\n");
++                      return NULL;
++              }
++
 +              /* back- and post-tracing length, post-trace length was frozen
 +                 in __ipipe_trace, back-trace may have to be reduced due to
 +                 buffer overrun */
@@ -12711,18 +12736,38 @@ index 0000000..5cce0bc
 +
 +extern struct proc_dir_entry *ipipe_proc_root;
 +
-+void __init __ipipe_init_tracer(void)
++void __init __ipipe_tracer_hrclock_initialized(void)
 +{
-+      struct proc_dir_entry *trace_dir;
 +      unsigned long long start, end, min = ULLONG_MAX;
 +      int i;
++
++#ifdef CONFIG_IPIPE_TRACE_VMALLOC
++      if (!per_cpu(trace_path, 0))
++              return;
++#endif
++      /* Calculate minimum overhead of __ipipe_trace() */
++      hard_local_irq_disable();
++      for (i = 0; i < 100; i++) {
++              ipipe_read_tsc(start);
++              __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
++                            __BUILTIN_RETURN_ADDRESS1, 0);
++              ipipe_read_tsc(end);
++
++              end -= start;
++              if (end < min)
++                      min = end;
++      }
++      hard_local_irq_enable();
++      trace_overhead = ipipe_tsc2ns(min);
++}
++
++void __init __ipipe_init_tracer(void)
++{
++      struct proc_dir_entry *trace_dir;
 +#ifdef CONFIG_IPIPE_TRACE_VMALLOC
 +      int cpu, path;
 +#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
 +
-+      if (!__ipipe_hrclock_ok())
-+              return;
-+
 +#ifdef CONFIG_IPIPE_TRACE_VMALLOC
 +      for_each_possible_cpu(cpu) {
 +              struct ipipe_trace_path *tp_buf;
@@ -12744,20 +12789,8 @@ index 0000000..5cce0bc
 +      }
 +#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
 +
-+      /* Calculate minimum overhead of __ipipe_trace() */
-+      hard_local_irq_disable();
-+      for (i = 0; i < 100; i++) {
-+              ipipe_read_tsc(start);
-+              __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
-+                            __BUILTIN_RETURN_ADDRESS1, 0);
-+              ipipe_read_tsc(end);
-+
-+              end -= start;
-+              if (end < min)
-+                      min = end;
-+      }
-+      hard_local_irq_enable();
-+      trace_overhead = ipipe_tsc2ns(min);
++      if (__ipipe_hrclock_ok() && !trace_overhead)
++              __ipipe_tracer_hrclock_initialized();
 +
 +#ifdef CONFIG_IPIPE_TRACE_ENABLE
 +      ipipe_trace_enable = 1;
@@ -12791,7 +12824,7 @@ index 0000000..5cce0bc
 +#endif /* !CONFIG_IPIPE_TRACE_MCOUNT */
 +}
 diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
-index cbd97ce..0faa00b 100644
+index cbd97ce..16ab280e 100644
 --- a/kernel/irq/chip.c
 +++ b/kernel/irq/chip.c
 @@ -15,6 +15,7 @@
@@ -12840,7 +12873,7 @@ index cbd97ce..0faa00b 100644
                desc->irq_data.chip->irq_shutdown(&desc->irq_data);
 -      else if (desc->irq_data.chip->irq_disable)
 +#ifdef CONFIG_IPIPE
-+              desc->istate |= ~IPIPE_IRQS_NEEDS_STARTUP;
++              desc->istate |= IPIPE_IRQS_NEEDS_STARTUP;
 +#endif
 +      } else if (desc->irq_data.chip->irq_disable)
                desc->irq_data.chip->irq_disable(&desc->irq_data);
@@ -13412,7 +13445,7 @@ index 1f3186b..5b710c8 100644
  
        if (curr->softirqs_enabled) {
 diff --git a/kernel/panic.c b/kernel/panic.c
-index 167ec09..cd078a7 100644
+index 167ec097..cd078a7 100644
 --- a/kernel/panic.c
 +++ b/kernel/panic.c
 @@ -22,6 +22,7 @@
@@ -14550,7 +14583,7 @@ index f8e0e53..02175aa3 100644
                        wake_up_klogd();
        }
 diff --git a/lib/ioremap.c b/lib/ioremap.c
-index 0c9216c..1575d3e 100644
+index 0c9216c..00a9a30 100644
 --- a/lib/ioremap.c
 +++ b/lib/ioremap.c
 @@ -10,6 +10,7 @@
@@ -14569,7 +14602,7 @@ index 0c9216c..1575d3e 100644
 +      /* APEI may invoke this for temporarily remapping pages in interrupt
 +       * context - nothing we can and need to propagate globally. */
 +      if (!in_interrupt()) {
-+              __ipipe_pin_range_globally(start, end);
++              __ipipe_pin_mapping_globally(start, end);
 +              flush_cache_vmap(start, end);
 +      }
  
@@ -14904,14 +14937,14 @@ index e9f65aa..d9a21ad 100644
  
        return pages;
 diff --git a/mm/vmalloc.c b/mm/vmalloc.c
-index d456560..b50a41d 100644
+index d456560..4083177 100644
 --- a/mm/vmalloc.c
 +++ b/mm/vmalloc.c
 @@ -191,6 +191,8 @@ static int vmap_page_range_noflush(unsigned long start, 
unsigned long end,
                        return err;
        } while (pgd++, addr = next, addr != end);
  
-+      __ipipe_pin_range_globally(start, end);
++      __ipipe_pin_mapping_globally(start, end);
 + 
        return nr;
  }
diff --git a/kernel/cobalt/arch/x86/patches/ipipe-core-3.14.39-x86-9.patch 
b/kernel/cobalt/arch/x86/patches/ipipe-core-3.14.44-x86-11.patch
similarity index 98%
rename from kernel/cobalt/arch/x86/patches/ipipe-core-3.14.39-x86-9.patch
rename to kernel/cobalt/arch/x86/patches/ipipe-core-3.14.44-x86-11.patch
index 9151f27..d22dfed 100644
--- a/kernel/cobalt/arch/x86/patches/ipipe-core-3.14.39-x86-9.patch
+++ b/kernel/cobalt/arch/x86/patches/ipipe-core-3.14.44-x86-11.patch
@@ -1,5 +1,5 @@
 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index 2f645c9..908b4f5 100644
+index 2f645c9..7efa6c4 100644
 --- a/arch/x86/Kconfig
 +++ b/arch/x86/Kconfig
 @@ -9,6 +9,7 @@ config 64BIT
@@ -10,17 +10,18 @@ index 2f645c9..908b4f5 100644
        select CLKSRC_I8253
        select HAVE_UID16
  
-@@ -21,6 +22,9 @@ config X86_64
+@@ -21,6 +22,10 @@ config X86_64
  ### Arch settings
  config X86
        def_bool y
 +      select IPIPE_HAVE_HOSTRT if IPIPE
 +      select IPIPE_HAVE_VM_NOTIFIER if IPIPE
 +      select IPIPE_HAVE_SAFE_THREAD_INFO if X86_64
++      select IPIPE_WANT_PTE_PINNING if IPIPE
        select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
-@@ -109,11 +113,11 @@ config X86
+@@ -109,11 +114,11 @@ config X86
        select GENERIC_CLOCKEVENTS
        select ARCH_CLOCKSOURCE_DATA if X86_64
        select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && 
X86_LOCAL_APIC)
@@ -34,7 +35,7 @@ index 2f645c9..908b4f5 100644
        select HAVE_IRQ_TIME_ACCOUNTING
        select VIRT_TO_BUS
        select MODULES_USE_ELF_REL if X86_32
-@@ -602,6 +606,7 @@ if HYPERVISOR_GUEST
+@@ -602,6 +607,7 @@ if HYPERVISOR_GUEST
  
  config PARAVIRT
        bool "Enable paravirtualization code"
@@ -42,7 +43,7 @@ index 2f645c9..908b4f5 100644
        ---help---
          This changes the kernel so it can modify itself when it is run
          under a hypervisor, potentially improving performance significantly
-@@ -852,6 +857,8 @@ config SCHED_MC
+@@ -852,6 +858,8 @@ config SCHED_MC
  
  source "kernel/Kconfig.preempt"
  
@@ -202,18 +203,10 @@ index 4b528a9..0cf06c6 100644
  static inline void debug_stack_usage_inc(void)
  {
 diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
-index a94b82e..e185603 100644
+index a94b82e..39fa15d 100644
 --- a/arch/x86/include/asm/desc.h
 +++ b/arch/x86/include/asm/desc.h
-@@ -4,6 +4,7 @@
- #include <asm/desc_defs.h>
- #include <asm/ldt.h>
- #include <asm/mmu.h>
-+#include <asm/hw_irq.h>
- 
- #include <linux/smp.h>
- #include <linux/percpu.h>
-@@ -376,11 +377,16 @@ static inline void _set_gate(int gate, unsigned type, 
void *addr,
+@@ -376,11 +376,16 @@ static inline void _set_gate(int gate, unsigned type, 
void *addr,
   * Pentium F0 0F bugfix can have resulted in the mapped
   * IDT being write-protected.
   */
@@ -231,7 +224,14 @@ index a94b82e..e185603 100644
                _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\
                                0, 0, __KERNEL_CS);                     \
        } while (0)
-@@ -392,6 +398,13 @@ extern unsigned long used_vectors[];
+@@ -389,9 +394,20 @@ extern int first_system_vector;
+ /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
+ extern unsigned long used_vectors[];
+ 
++#ifdef CONFIG_IPIPE
++extern int vector_irq[NR_VECTORS];
++#endif
++
  static inline void alloc_system_vector(int vector)
  {
        if (!test_bit(vector, used_vectors)) {
@@ -245,7 +245,7 @@ index a94b82e..e185603 100644
                set_bit(vector, used_vectors);
                if (first_system_vector > vector)
                        first_system_vector = vector;
-@@ -400,6 +413,12 @@ static inline void alloc_system_vector(int vector)
+@@ -400,6 +416,12 @@ static inline void alloc_system_vector(int vector)
        }
  }
  
@@ -258,7 +258,7 @@ index a94b82e..e185603 100644
  #define alloc_intr_gate(n, addr)                              \
        do {                                                    \
                alloc_system_vector(n);                         \
-@@ -445,7 +464,7 @@ static inline void set_system_intr_gate_ist(int n, void 
*addr, unsigned ist)
+@@ -445,7 +467,7 @@ static inline void set_system_intr_gate_ist(int n, void 
*addr, unsigned ist)
        _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
  }
  
@@ -442,7 +442,7 @@ index 615fa90..e0a62ab 100644
  extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
 diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h
 new file mode 100644
-index 0000000..6766b3d
+index 0000000..4ad79ed
 --- /dev/null
 +++ b/arch/x86/include/asm/ipipe.h
 @@ -0,0 +1,96 @@
@@ -472,7 +472,7 @@ index 0000000..6766b3d
 +
 +#ifdef CONFIG_IPIPE
 +
-+#define IPIPE_CORE_RELEASE    9
++#define IPIPE_CORE_RELEASE    11
 +
 +struct ipipe_domain;
 +
@@ -747,7 +747,7 @@ index 0000000..d000d7e
 +#endif        /* !__X86_IPIPE_64_H */
 diff --git a/arch/x86/include/asm/ipipe_base.h 
b/arch/x86/include/asm/ipipe_base.h
 new file mode 100644
-index 0000000..3ebadc1
+index 0000000..f665cfa
 --- /dev/null
 +++ b/arch/x86/include/asm/ipipe_base.h
 @@ -0,0 +1,231 @@
@@ -857,7 +857,7 @@ index 0000000..3ebadc1
 +#endif
 +}
 +
-+void __ipipe_halt_root(void);
++void __ipipe_halt_root(int use_mwait);
 +
 +void ipipe_hrtimer_interrupt(void);
 +
@@ -1012,7 +1012,7 @@ index 5702d7e..dd61aa6 100644
  
  #define FPU_IRQ                                 13
 diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
-index 0a8b519..0d052b7 100644
+index 0a8b519..c52d5e0 100644
 --- a/arch/x86/include/asm/irqflags.h
 +++ b/arch/x86/include/asm/irqflags.h
 @@ -4,6 +4,11 @@
@@ -1093,7 +1093,7 @@ index 0a8b519..0d052b7 100644
  {
 +#ifdef CONFIG_IPIPE
 +      barrier();
-+      __ipipe_halt_root();
++      __ipipe_halt_root(0);
 +#else
        native_safe_halt();
 +#endif
@@ -1664,7 +1664,7 @@ index 2c621a6..18b3219 100644
  
  static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
 diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
-index 6ad4658..9233e45 100644
+index 6ad4658..170ee2d 100644
 --- a/arch/x86/kernel/apic/io_apic.c
 +++ b/arch/x86/kernel/apic/io_apic.c
 @@ -71,8 +71,8 @@
@@ -1728,7 +1728,7 @@ index 6ad4658..9233e45 100644
  }
  
  /*
-@@ -578,18 +585,28 @@ void native_eoi_ioapic_pin(int apic, int pin, int vector)
+@@ -578,15 +585,21 @@ void native_eoi_ioapic_pin(int apic, int pin, int vector)
        }
  }
  
@@ -1744,8 +1744,6 @@ index 6ad4658..9233e45 100644
                                               cfg->vector);
 +}
 +
-+#if !defined(CONFIG_IPIPE) || defined(CONFIG_SMP)
-+
 +void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
 +{
 +      unsigned long flags;
@@ -1755,12 +1753,7 @@ index 6ad4658..9233e45 100644
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
  }
  
-+#endif /* !CONFIG_IPIPE || CONFIG_SMP */
-+
- static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
- {
-       struct IO_APIC_route_entry entry;
-@@ -1222,8 +1239,19 @@ void __setup_vector_irq(int cpu)
+@@ -1222,8 +1235,19 @@ void __setup_vector_irq(int cpu)
                vector = cfg->vector;
                per_cpu(vector_irq, cpu)[vector] = irq;
        }
@@ -1780,7 +1773,7 @@ index 6ad4658..9233e45 100644
                irq = per_cpu(vector_irq, cpu)[vector];
                if (irq <= VECTOR_UNDEFINED)
                        continue;
-@@ -1309,6 +1337,19 @@ int native_setup_ioapic_entry(int irq, struct 
IO_APIC_route_entry *entry,
+@@ -1309,6 +1333,19 @@ int native_setup_ioapic_entry(int irq, struct 
IO_APIC_route_entry *entry,
        return 0;
  }
  
@@ -1800,7 +1793,7 @@ index 6ad4658..9233e45 100644
  static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
                                struct io_apic_irq_attr *attr)
  {
-@@ -1346,7 +1387,7 @@ static void setup_ioapic_irq(unsigned int irq, struct 
irq_cfg *cfg,
+@@ -1346,7 +1383,7 @@ static void setup_ioapic_irq(unsigned int irq, struct 
irq_cfg *cfg,
  
        ioapic_register_intr(irq, cfg, attr->trigger);
        if (irq < legacy_pic->nr_legacy_irqs)
@@ -1809,7 +1802,7 @@ index 6ad4658..9233e45 100644
  
        ioapic_write_entry(attr->ioapic, attr->ioapic_pin, entry);
  }
-@@ -2139,11 +2180,12 @@ static unsigned int startup_ioapic_irq(struct irq_data 
*data)
+@@ -2139,11 +2176,12 @@ static unsigned int startup_ioapic_irq(struct irq_data 
*data)
  
        raw_spin_lock_irqsave(&ioapic_lock, flags);
        if (irq < legacy_pic->nr_legacy_irqs) {
@@ -1823,7 +1816,7 @@ index 6ad4658..9233e45 100644
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
  
        return was_pending;
-@@ -2198,7 +2240,8 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
+@@ -2198,7 +2236,8 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
        exit_idle();
  
        me = smp_processor_id();
@@ -1833,7 +1826,7 @@ index 6ad4658..9233e45 100644
                int irq;
                unsigned int irr;
                struct irq_desc *desc;
-@@ -2359,14 +2402,16 @@ int native_ioapic_set_affinity(struct irq_data *data,
+@@ -2359,14 +2398,16 @@ int native_ioapic_set_affinity(struct irq_data *data,
  
  static void ack_apic_edge(struct irq_data *data)
  {
@@ -1852,7 +1845,7 @@ index 6ad4658..9233e45 100644
  static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
  {
        struct irq_pin_list *entry;
-@@ -2394,7 +2439,7 @@ static inline bool ioapic_irqd_mask(struct irq_data 
*data, struct irq_cfg *cfg)
+@@ -2394,7 +2435,7 @@ static inline bool ioapic_irqd_mask(struct irq_data 
*data, struct irq_cfg *cfg)
  {
        /* If we are moving the irq we need to mask it */
        if (unlikely(irqd_is_setaffinity_pending(data))) {
@@ -1861,7 +1854,7 @@ index 6ad4658..9233e45 100644
                return true;
        }
        return false;
-@@ -2432,7 +2477,7 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
+@@ -2432,7 +2473,7 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
                 */
                if (!io_apic_level_ack_pending(cfg))
                        irq_move_masked_irq(data);
@@ -1870,7 +1863,7 @@ index 6ad4658..9233e45 100644
        }
  }
  #else
-@@ -2446,12 +2491,46 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
+@@ -2446,12 +2487,46 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
  }
  #endif
  
@@ -1918,7 +1911,7 @@ index 6ad4658..9233e45 100644
  
        irq_complete_move(cfg);
        masked = ioapic_irqd_mask(data, cfg);
-@@ -2511,8 +2590,50 @@ static void ack_apic_level(struct irq_data *data)
+@@ -2511,8 +2586,50 @@ static void ack_apic_level(struct irq_data *data)
        }
  
        ioapic_irqd_unmask(data, cfg, masked);
@@ -1952,8 +1945,8 @@ index 6ad4658..9233e45 100644
 +      __mask_ioapic(cfg);
 +      raw_spin_unlock(&ioapic_lock);
 +      ack_apic_level(data);
-+}
-+
+ }
+ 
 +static void release_ioapic_irq(struct irq_data *data)
 +{
 +      struct irq_cfg *cfg = data->chip_data;
@@ -1962,14 +1955,14 @@ index 6ad4658..9233e45 100644
 +      raw_spin_lock_irqsave(&ioapic_lock, flags);
 +      __unmask_ioapic(cfg);
 +      raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- }
- 
++}
++
 +#endif        /* CONFIG_IPIPE */
 +
  static struct irq_chip ioapic_chip __read_mostly = {
        .name                   = "IO-APIC",
        .irq_startup            = startup_ioapic_irq,
-@@ -2522,6 +2643,13 @@ static struct irq_chip ioapic_chip __read_mostly = {
+@@ -2522,6 +2639,13 @@ static struct irq_chip ioapic_chip __read_mostly = {
        .irq_eoi                = ack_apic_level,
        .irq_set_affinity       = native_ioapic_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -1983,7 +1976,7 @@ index 6ad4658..9233e45 100644
  };
  
  static inline void init_IO_APIC_traps(void)
-@@ -2563,23 +2691,29 @@ static inline void init_IO_APIC_traps(void)
+@@ -2563,23 +2687,29 @@ static inline void init_IO_APIC_traps(void)
  
  static void mask_lapic_irq(struct irq_data *data)
  {
@@ -2016,7 +2009,7 @@ index 6ad4658..9233e45 100644
  }
  
  static struct irq_chip lapic_chip __read_mostly = {
-@@ -2587,6 +2721,9 @@ static struct irq_chip lapic_chip __read_mostly = {
+@@ -2587,6 +2717,9 @@ static struct irq_chip lapic_chip __read_mostly = {
        .irq_mask       = mask_lapic_irq,
        .irq_unmask     = unmask_lapic_irq,
        .irq_ack        = ack_lapic_irq,
@@ -2026,7 +2019,7 @@ index 6ad4658..9233e45 100644
  };
  
  static void lapic_register_intr(int irq)
-@@ -2687,7 +2824,7 @@ static inline void __init check_timer(void)
+@@ -2687,7 +2820,7 @@ static inline void __init check_timer(void)
        /*
         * get/set the timer IRQ vector:
         */
@@ -2035,7 +2028,7 @@ index 6ad4658..9233e45 100644
        assign_irq_vector(0, cfg, apic->target_cpus());
  
        /*
-@@ -2744,7 +2881,7 @@ static inline void __init check_timer(void)
+@@ -2744,7 +2877,7 @@ static inline void __init check_timer(void)
                        int idx;
                        idx = find_irq_entry(apic1, pin1, mp_INT);
                        if (idx != -1 && irq_trigger(idx))
@@ -2044,7 +2037,7 @@ index 6ad4658..9233e45 100644
                }
                if (timer_irq_works()) {
                        if (disable_timer_pin_1 > 0)
-@@ -2777,7 +2914,7 @@ static inline void __init check_timer(void)
+@@ -2777,7 +2910,7 @@ static inline void __init check_timer(void)
                 * Cleanup, just in case ...
                 */
                local_irq_disable();
@@ -2053,7 +2046,7 @@ index 6ad4658..9233e45 100644
                clear_IO_APIC_pin(apic2, pin2);
                apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
        }
-@@ -2786,6 +2923,10 @@ static inline void __init check_timer(void)
+@@ -2786,6 +2919,10 @@ static inline void __init check_timer(void)
                    "...trying to set up timer as Virtual Wire IRQ...\n");
  
        lapic_register_intr(0);
@@ -2064,7 +2057,7 @@ index 6ad4658..9233e45 100644
        apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);     /* Fixed mode */
        legacy_pic->unmask(0);
  
-@@ -2794,7 +2935,7 @@ static inline void __init check_timer(void)
+@@ -2794,7 +2931,7 @@ static inline void __init check_timer(void)
                goto out;
        }
        local_irq_disable();
@@ -2073,7 +2066,7 @@ index 6ad4658..9233e45 100644
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
        apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
  
-@@ -3102,6 +3243,9 @@ static struct irq_chip msi_chip = {
+@@ -3102,6 +3239,9 @@ static struct irq_chip msi_chip = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = msi_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2083,7 +2076,7 @@ index 6ad4658..9233e45 100644
  };
  
  int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
-@@ -3201,6 +3345,9 @@ static struct irq_chip dmar_msi_type = {
+@@ -3201,6 +3341,9 @@ static struct irq_chip dmar_msi_type = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = dmar_msi_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2093,7 +2086,7 @@ index 6ad4658..9233e45 100644
  };
  
  int arch_setup_dmar_msi(unsigned int irq)
-@@ -3249,6 +3396,9 @@ static struct irq_chip hpet_msi_type = {
+@@ -3249,6 +3392,9 @@ static struct irq_chip hpet_msi_type = {
        .irq_ack = ack_apic_edge,
        .irq_set_affinity = hpet_msi_set_affinity,
        .irq_retrigger = ioapic_retrigger_irq,
@@ -2103,7 +2096,7 @@ index 6ad4658..9233e45 100644
  };
  
  int default_setup_hpet_msi(unsigned int irq, unsigned int id)
-@@ -3310,6 +3460,9 @@ static struct irq_chip ht_irq_chip = {
+@@ -3310,6 +3456,9 @@ static struct irq_chip ht_irq_chip = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = ht_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2113,7 +2106,7 @@ index 6ad4658..9233e45 100644
  };
  
  int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
-@@ -3597,6 +3750,18 @@ int acpi_get_override_irq(u32 gsi, int *trigger, int 
*polarity)
+@@ -3597,6 +3746,18 @@ int acpi_get_override_irq(u32 gsi, int *trigger, int 
*polarity)
        return 0;
  }
  
@@ -3689,10 +3682,10 @@ index 2e977b5..e91576e 100644
  handle_real_irq:
 diff --git a/arch/x86/kernel/ipipe.c b/arch/x86/kernel/ipipe.c
 new file mode 100644
-index 0000000..1bcee82
+index 0000000..e556d14
 --- /dev/null
 +++ b/arch/x86/kernel/ipipe.c
-@@ -0,0 +1,584 @@
+@@ -0,0 +1,574 @@
 +/*   -*- linux-c -*-
 + *   linux/arch/x86/kernel/ipipe.c
 + *
@@ -3755,20 +3748,6 @@ index 0000000..1bcee82
 +DEFINE_PER_CPU(unsigned long, __ipipe_cr2);
 +EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_cr2);
 +
-+void ipipe_raise_irq(unsigned int irq)
-+{
-+      struct pt_regs regs;
-+      unsigned long flags;
-+
-+      flags = hard_local_irq_save();
-+      regs.flags = flags;
-+      regs.orig_ax = irq;  /* >= 0, IRQ won't be acked */
-+      regs.cs = __KERNEL_CS;
-+      __ipipe_handle_irq(&regs);
-+      hard_local_irq_restore(flags);
-+}
-+EXPORT_SYMBOL_GPL(ipipe_raise_irq);
-+
 +int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
 +{
 +      info->sys_nr_cpus = num_online_cpus();
@@ -3981,7 +3960,7 @@ index 0000000..1bcee82
 +              regs->flags |= X86_EFLAGS_IF;
 +}
 +
-+void __ipipe_halt_root(void)
++void __ipipe_halt_root(int use_mwait)
 +{
 +      struct ipipe_percpu_domain_data *p;
 +
@@ -4001,7 +3980,11 @@ index 0000000..1bcee82
 +#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
 +              ipipe_trace_end(0x8000000E);
 +#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
-+              asm volatile("sti; hlt": : :"memory");
++              if (use_mwait)
++                      asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
++                                   :: "a" (0), "c" (0));
++              else
++                      asm volatile("sti; hlt": : :"memory");
 +      }
 +}
 +EXPORT_SYMBOL_GPL(__ipipe_halt_root);
@@ -4437,10 +4420,10 @@ index a311ffc..482b42f 100644
  
        return IS_ERR(pd) ? PTR_ERR(pd) : 0;
 diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
-index 3fb8d95..5b7d190 100644
+index 1a1ff42..30d929c 100644
 --- a/arch/x86/kernel/process.c
 +++ b/arch/x86/kernel/process.c
-@@ -93,6 +93,10 @@ void arch_task_cache_init(void)
+@@ -94,6 +94,10 @@ void arch_task_cache_init(void)
                kmem_cache_create("task_xstate", xstate_size,
                                  __alignof__(union thread_xstate),
                                  SLAB_PANIC | SLAB_NOTRACK, NULL);
@@ -4451,7 +4434,7 @@ index 3fb8d95..5b7d190 100644
  }
  
  /*
-@@ -107,8 +111,16 @@ void exit_thread(void)
+@@ -108,8 +112,16 @@ void exit_thread(void)
        if (bp) {
                struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
  
@@ -4469,7 +4452,7 @@ index 3fb8d95..5b7d190 100644
                /*
                 * Careful, clear this in the TSS too:
                 */
-@@ -128,12 +140,14 @@ void flush_thread(void)
+@@ -129,12 +141,14 @@ void flush_thread(void)
        flush_ptrace_hw_breakpoint(tsk);
        memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
        drop_init_fpu(tsk);
@@ -4484,7 +4467,7 @@ index 3fb8d95..5b7d190 100644
  }
  
  static void hard_disable_TSC(void)
-@@ -329,7 +343,7 @@ bool xen_set_default_idle(void)
+@@ -330,7 +344,7 @@ bool xen_set_default_idle(void)
  #endif
  void stop_this_cpu(void *dummy)
  {
@@ -4493,7 +4476,7 @@ index 3fb8d95..5b7d190 100644
        /*
         * Remove this CPU:
         */
-@@ -368,6 +382,10 @@ static void amd_e400_idle(void)
+@@ -369,6 +383,10 @@ static void amd_e400_idle(void)
                        if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
                                mark_tsc_unstable("TSC halt in AMD C1E");
                        pr_info("System has AMD C1E enabled\n");
@@ -4504,6 +4487,18 @@ index 3fb8d95..5b7d190 100644
                }
        }
  
+@@ -437,7 +455,11 @@ static void mwait_idle(void)
+ 
+               __monitor((void *)&current_thread_info()->flags, 0, 0);
+               if (!need_resched())
++#ifdef CONFIG_IPIPE
++                      __ipipe_halt_root(1);
++#else
+                       __sti_mwait(0, 0);
++#endif
+               else
+                       local_irq_enable();
+       } else
 diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
 index 0de43e9..46f88a9 100644
 --- a/arch/x86/kernel/process_32.c
@@ -5083,7 +5078,7 @@ index ddf9ecb..e1ac76d 100644
  
        /*
 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
-index a10c8c7..f12bbb9 100644
+index ebc551c..5ce2100 100644
 --- a/arch/x86/mm/fault.c
 +++ b/arch/x86/mm/fault.c
 @@ -358,9 +358,9 @@ void vmalloc_sync_all(void)
@@ -5119,7 +5114,7 @@ index a10c8c7..f12bbb9 100644
  #ifdef CONFIG_CPU_SUP_AMD
  static const char errata93_warning[] =
  KERN_ERR 
-@@ -1038,6 +1043,11 @@ __do_page_fault(struct pt_regs *regs, unsigned long 
error_code,
+@@ -1033,6 +1038,11 @@ __do_page_fault(struct pt_regs *regs, unsigned long 
error_code,
        tsk = current;
        mm = tsk->mm;
  
@@ -5131,12 +5126,12 @@ index a10c8c7..f12bbb9 100644
        /*
         * Detect and handle instructions that would cause a page fault for
         * both a tracked kernel page and a userspace page.
-@@ -1268,6 +1278,46 @@ do_page_fault(struct pt_regs *regs, unsigned long 
error_code)
+@@ -1264,6 +1274,46 @@ do_page_fault(struct pt_regs *regs, unsigned long 
error_code)
        exception_exit(prev_state);
  }
  
 +#ifdef CONFIG_IPIPE
-+void __ipipe_pin_range_globally(unsigned long start, unsigned long end)
++void __ipipe_pin_mapping_globally(unsigned long start, unsigned long end)
 +{
 +#ifdef CONFIG_X86_32
 +      unsigned long next, addr = start;
@@ -5178,7 +5173,7 @@ index a10c8c7..f12bbb9 100644
  #ifdef CONFIG_TRACING
  static void trace_page_fault_entries(unsigned long address, struct pt_regs 
*regs,
                                     unsigned long error_code)
-@@ -1295,4 +1345,5 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long 
error_code)
+@@ -1291,4 +1341,5 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long 
error_code)
        __do_page_fault(regs, error_code, address);
        exception_exit(prev_state);
  }
@@ -5493,6 +5488,25 @@ index f04e25f..5fa6be6 100644
        select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
        select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
        help
+diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
+index 228632c9..3da4d6d 100644
+--- a/drivers/iommu/irq_remapping.c
++++ b/drivers/iommu/irq_remapping.c
+@@ -361,12 +361,12 @@ void panic_if_irq_remap(const char *msg)
+ 
+ static void ir_ack_apic_edge(struct irq_data *data)
+ {
+-      ack_APIC_irq();
++      __ack_APIC_irq();
+ }
+ 
+ static void ir_ack_apic_level(struct irq_data *data)
+ {
+-      ack_APIC_irq();
++      __ack_APIC_irq();
+       eoi_ioapic_irq(data->irq, data->chip_data);
+ }
+ 
 diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
 index 612dfc7..ffd8160 100644
 --- a/drivers/tty/serial/8250/8250_core.c
@@ -5583,7 +5597,7 @@ index 612dfc7..ffd8160 100644
        .probe          = serial8250_probe,
        .remove         = serial8250_remove,
 diff --git a/fs/exec.c b/fs/exec.c
-index ea4449d..aa73a12 100644
+index 05f1942..836253a 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -822,6 +822,7 @@ static int exec_mmap(struct mm_struct *mm)
@@ -5900,10 +5914,10 @@ index e6bb36a..898a91a 100644
  
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..912f689
+index 0000000..fc31c97
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,455 @@
+@@ -0,0 +1,461 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -6320,6 +6334,12 @@ index 0000000..912f689
 +#define __ipipe_uaccess_might_fault() might_fault()
 +#endif
 +
++#ifdef CONFIG_IPIPE_TRACE
++void __ipipe_tracer_hrclock_initialized(void);
++#else /* !CONFIG_IPIPE_TRACE */
++#define __ipipe_tracer_hrclock_initialized()  do { } while(0)
++#endif /* !CONFIG_IPIPE_TRACE */
++
 +#include <linux/ipipe_compat.h>
 +
 +#else /* !CONFIG_IPIPE */
@@ -6361,10 +6381,10 @@ index 0000000..912f689
 +#endif        /* !__LINUX_IPIPE_H */
 diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
 new file mode 100644
-index 0000000..ea01dd6
+index 0000000..a37358c
 --- /dev/null
 +++ b/include/linux/ipipe_base.h
-@@ -0,0 +1,356 @@
+@@ -0,0 +1,358 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_base.h
 + *
@@ -6546,9 +6566,6 @@ index 0000000..ea01dd6
 +
 +void __ipipe_flush_printk(unsigned int irq, void *cookie);
 +
-+void __ipipe_pin_range_globally(unsigned long start,
-+                              unsigned long end);
-+
 +#define __ipipe_get_cpu(flags)        ({ (flags) = hard_preempt_disable(); 
ipipe_processor_id(); })
 +#define __ipipe_put_cpu(flags)        hard_preempt_enable(flags)
 +
@@ -6681,10 +6698,6 @@ index 0000000..ea01dd6
 +
 +static inline void __ipipe_init_taskinfo(struct task_struct *p) { }
 +
-+static inline void __ipipe_pin_range_globally(unsigned long start,
-+                                            unsigned long end)
-+{ }
-+
 +#define hard_preempt_disable()                ({ preempt_disable(); 0; })
 +#define hard_preempt_enable(flags)    ({ preempt_enable(); (void)(flags); })
 +
@@ -6711,6 +6724,15 @@ index 0000000..ea01dd6
 +
 +#endif        /* !CONFIG_IPIPE */
 +
++#ifdef CONFIG_IPIPE_WANT_PTE_PINNING
++void __ipipe_pin_mapping_globally(unsigned long start,
++                                unsigned long end);
++#else
++static inline void __ipipe_pin_mapping_globally(unsigned long start,
++                                              unsigned long end)
++{ }
++#endif
++
 +static inline void ipipe_preempt_root_only(void)
 +{
 +#if defined(CONFIG_IPIPE_DEBUG_CONTEXT) && \
@@ -8228,7 +8250,7 @@ index 5b9b84b..6c8bb4d 100644
  static inline void __raw_read_lock(rwlock_t *lock)
  {
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 218b058..d579687 100644
+index 91fe6a3..d579687 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -24,6 +24,7 @@ struct sched_param {
@@ -8294,15 +8316,6 @@ index 218b058..d579687 100644
  
        /*
         * cache last used pipe for splice
-@@ -1695,7 +1719,7 @@ static inline pid_t task_tgid_vnr(struct task_struct 
*tsk)
- }
- 
- 
--static int pid_alive(const struct task_struct *p);
-+static inline int pid_alive(const struct task_struct *p);
- static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct 
pid_namespace *ns)
- {
-       pid_t pid = 0;
 diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
 index 3f2867f..336c90a 100644
 --- a/include/linux/spinlock.h
@@ -8908,10 +8921,10 @@ index e2c6853..68c5ef5a 100644
        trace_task_newtask(p, clone_flags);
 diff --git a/kernel/ipipe/Kconfig b/kernel/ipipe/Kconfig
 new file mode 100644
-index 0000000..da17b04
+index 0000000..218f51da
 --- /dev/null
 +++ b/kernel/ipipe/Kconfig
-@@ -0,0 +1,62 @@
+@@ -0,0 +1,65 @@
 +config IPIPE
 +      bool "Interrupt pipeline"
 +      default y
@@ -8932,6 +8945,9 @@ index 0000000..da17b04
 +config IPIPE_WANT_CLOCKSOURCE
 +       bool
 +
++config IPIPE_WANT_PTE_PINNING
++       bool
++
 +config IPIPE_CORE_APIREV
 +       int
 +       depends on IPIPE
@@ -9365,10 +9381,10 @@ index 0000000..797a849
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..c5b022b
+index 0000000..026f6d9
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1929 @@
+@@ -0,0 +1,1956 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -10770,6 +10786,33 @@ index 0000000..c5b022b
 +      __ipipe_sync_pipeline(ipipe_head_domain);
 +}
 +
++void ipipe_raise_irq(unsigned int irq)
++{
++      struct ipipe_domain *ipd = ipipe_head_domain;
++      unsigned long flags, control;
++
++      flags = hard_local_irq_save();
++
++      /*
++       * Fast path: raising a virtual IRQ handled by the head
++       * domain.
++       */
++      if (likely(ipipe_virtual_irq_p(irq) && ipd != ipipe_root_domain)) {
++              control = ipd->irqs[irq].control;
++              if (likely(control & IPIPE_HANDLE_MASK)) {
++                      dispatch_irq_head(irq);
++                      goto out;
++              }
++      }
++
++      /* Emulate regular device IRQ receipt. */
++      __ipipe_dispatch_irq(irq, IPIPE_IRQF_NOACK);
++out:
++      hard_local_irq_restore(flags);
++
++}
++EXPORT_SYMBOL_GPL(ipipe_raise_irq);
++
 +#ifdef CONFIG_PREEMPT
 +
 +void preempt_schedule_irq(void);
@@ -11300,10 +11343,10 @@ index 0000000..c5b022b
 +#endif
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..0c9b908
+index 0000000..f32a7ff
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,492 @@
+@@ -0,0 +1,493 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -11671,6 +11714,7 @@ index 0000000..0c9b908
 +              timer->real_set_next_event = evtdev->set_next_event;
 +              evtdev->mult = 1;
 +              evtdev->shift = 0;
++              evtdev->max_delta_ns = UINT_MAX;
 +              evtdev->set_mode = emumode;
 +              evtdev->set_next_event = emutick;
 +              evtdev->ipipe_stolen = 1;
@@ -11798,10 +11842,10 @@ index 0000000..0c9b908
 +#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..5cce0bc
+index 0000000..8388671
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
-@@ -0,0 +1,1447 @@
+@@ -0,0 +1,1468 @@
 +/* -*- linux-c -*-
 + * kernel/ipipe/tracer.c
 + *
@@ -12549,6 +12593,9 @@ index 0000000..5cce0bc
 +      unsigned long long abs_tsc;
 +      long us;
 +
++      if (!__ipipe_hrclock_ok())
++              return 0;
++
 +      /* ipipe_tsc2us works on unsigned => handle sign separately */
 +      abs_tsc = (tsc >= 0) ? tsc : -tsc;
 +      us = ipipe_tsc2us(abs_tsc);
@@ -12751,6 +12798,11 @@ index 0000000..5cce0bc
 +
 +              __ipipe_global_path_unlock(flags);
 +
++              if (!__ipipe_hrclock_ok()) {
++                      seq_printf(m, "No hrclock available, dumping traces 
disabled\n");
++                      return NULL;
++              }
++
 +              /* does this path actually contain data? */
 +              if (print_path->end == print_path->begin)
 +                      return NULL;
@@ -12921,6 +12973,11 @@ index 0000000..5cce0bc
 +              if (!print_path)
 +                      return NULL;
 +
++              if (!__ipipe_hrclock_ok()) {
++                      seq_printf(m, "No hrclock available, dumping traces 
disabled\n");
++                      return NULL;
++              }
++
 +              /* back- and post-tracing length, post-trace length was frozen
 +                 in __ipipe_trace, back-trace may have to be reduced due to
 +                 buffer overrun */
@@ -13170,18 +13227,38 @@ index 0000000..5cce0bc
 +
 +extern struct proc_dir_entry *ipipe_proc_root;
 +
-+void __init __ipipe_init_tracer(void)
++void __init __ipipe_tracer_hrclock_initialized(void)
 +{
-+      struct proc_dir_entry *trace_dir;
 +      unsigned long long start, end, min = ULLONG_MAX;
 +      int i;
++
++#ifdef CONFIG_IPIPE_TRACE_VMALLOC
++      if (!per_cpu(trace_path, 0))
++              return;
++#endif
++      /* Calculate minimum overhead of __ipipe_trace() */
++      hard_local_irq_disable();
++      for (i = 0; i < 100; i++) {
++              ipipe_read_tsc(start);
++              __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
++                            __BUILTIN_RETURN_ADDRESS1, 0);
++              ipipe_read_tsc(end);
++
++              end -= start;
++              if (end < min)
++                      min = end;
++      }
++      hard_local_irq_enable();
++      trace_overhead = ipipe_tsc2ns(min);
++}
++
++void __init __ipipe_init_tracer(void)
++{
++      struct proc_dir_entry *trace_dir;
 +#ifdef CONFIG_IPIPE_TRACE_VMALLOC
 +      int cpu, path;
 +#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
 +
-+      if (!__ipipe_hrclock_ok())
-+              return;
-+
 +#ifdef CONFIG_IPIPE_TRACE_VMALLOC
 +      for_each_possible_cpu(cpu) {
 +              struct ipipe_trace_path *tp_buf;
@@ -13203,20 +13280,8 @@ index 0000000..5cce0bc
 +      }
 +#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
 +
-+      /* Calculate minimum overhead of __ipipe_trace() */
-+      hard_local_irq_disable();
-+      for (i = 0; i < 100; i++) {
-+              ipipe_read_tsc(start);
-+              __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
-+                            __BUILTIN_RETURN_ADDRESS1, 0);
-+              ipipe_read_tsc(end);
-+
-+              end -= start;
-+              if (end < min)
-+                      min = end;
-+      }
-+      hard_local_irq_enable();
-+      trace_overhead = ipipe_tsc2ns(min);
++      if (__ipipe_hrclock_ok() && !trace_overhead)
++              __ipipe_tracer_hrclock_initialized();
 +
 +#ifdef CONFIG_IPIPE_TRACE_ENABLE
 +      ipipe_trace_enable = 1;
@@ -13250,7 +13315,7 @@ index 0000000..5cce0bc
 +#endif /* !CONFIG_IPIPE_TRACE_MCOUNT */
 +}
 diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
-index dc04c16..2296ca9 100644
+index dc04c16..dff8902 100644
 --- a/kernel/irq/chip.c
 +++ b/kernel/irq/chip.c
 @@ -15,6 +15,7 @@
@@ -13299,7 +13364,7 @@ index dc04c16..2296ca9 100644
                desc->irq_data.chip->irq_shutdown(&desc->irq_data);
 -      else if (desc->irq_data.chip->irq_disable)
 +#ifdef CONFIG_IPIPE
-+              desc->istate |= ~IPIPE_IRQS_NEEDS_STARTUP;
++              desc->istate |= IPIPE_IRQS_NEEDS_STARTUP;
 +#endif
 +      } else if (desc->irq_data.chip->irq_disable)
                desc->irq_data.chip->irq_disable(&desc->irq_data);
@@ -14782,20 +14847,20 @@ index e3be87e..e6a7b54 100644
        /* ftrace_dyn_arch_init places the return code in addr */
        if (addr)
 diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
-index 774a080..8b2f9dd 100644
+index da41de9..82df76d8 100644
 --- a/kernel/trace/ring_buffer.c
 +++ b/kernel/trace/ring_buffer.c
 @@ -2651,7 +2651,8 @@ static DEFINE_PER_CPU(unsigned int, current_context);
  
  static __always_inline int trace_recursive_lock(void)
  {
--      unsigned int val = this_cpu_read(current_context);
+-      unsigned int val = __this_cpu_read(current_context);
 +      unsigned long flags;
 +      unsigned int val;
        int bit;
  
        if (in_interrupt()) {
-@@ -2664,22 +2665,35 @@ static __always_inline int trace_recursive_lock(void)
+@@ -2664,21 +2665,34 @@ static __always_inline int trace_recursive_lock(void)
        } else
                bit = 3;
  
@@ -14809,35 +14874,31 @@ index 774a080..8b2f9dd 100644
 +      }
  
        val |= (1 << bit);
--      this_cpu_write(current_context, val);
-+      __this_cpu_write(current_context, val);
-+
-+      hard_local_irq_restore(flags);
+       __this_cpu_write(current_context, val);
  
++      hard_local_irq_restore(flags);
++
        return 0;
  }
  
  static __always_inline void trace_recursive_unlock(void)
  {
--      unsigned int val = this_cpu_read(current_context);
+-      unsigned int val = __this_cpu_read(current_context);
 +      unsigned long flags;
 +      unsigned int val;
 +
 +      flags = hard_local_irq_save();
  
 +      val = __this_cpu_read(current_context);
-       val--;
--      val &= this_cpu_read(current_context);
--      this_cpu_write(current_context, val);
-+      val &= __this_cpu_read(current_context);
-+      __this_cpu_write(current_context, val);
+       val &= val & (val - 1);
+       __this_cpu_write(current_context, val);
 +
 +      hard_local_irq_restore(flags);
  }
  
  #else
 diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
-index 813b021..6911c85 100644
+index a2d62b3..38b8ba8 100644
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
 @@ -2053,8 +2053,9 @@ int trace_vbprintk(unsigned long ip, const char *fmt, 
va_list args)
@@ -15162,7 +15223,7 @@ index f8e0e53..02175aa3 100644
                        wake_up_klogd();
        }
 diff --git a/lib/ioremap.c b/lib/ioremap.c
-index 0c9216c..1575d3e 100644
+index 0c9216c..00a9a30 100644
 --- a/lib/ioremap.c
 +++ b/lib/ioremap.c
 @@ -10,6 +10,7 @@
@@ -15181,7 +15242,7 @@ index 0c9216c..1575d3e 100644
 +      /* APEI may invoke this for temporarily remapping pages in interrupt
 +       * context - nothing we can and need to propagate globally. */
 +      if (!in_interrupt()) {
-+              __ipipe_pin_range_globally(start, end);
++              __ipipe_pin_mapping_globally(start, end);
 +              flush_cache_vmap(start, end);
 +      }
  
@@ -15219,7 +15280,7 @@ index 0862816..aacbf2df 100644
        help
          Transparent Hugepages allows the kernel to use huge pages and
 diff --git a/mm/memory.c b/mm/memory.c
-index 102af09..7d9fc91 100644
+index 749e1c6..090df7e 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
 @@ -788,6 +788,34 @@ out:
@@ -15347,7 +15408,7 @@ index 102af09..7d9fc91 100644
                if (entry.val)
                        break;
                progress += 8;
-@@ -2563,34 +2637,6 @@ static inline int pte_unmap_same(struct mm_struct *mm, 
pmd_t *pmd,
+@@ -2564,34 +2638,6 @@ static inline int pte_unmap_same(struct mm_struct *mm, 
pmd_t *pmd,
        return same;
  }
  
@@ -15382,7 +15443,7 @@ index 102af09..7d9fc91 100644
  /*
   * This routine handles present pages, when users try to write
   * to a shared page. It is done by copying the page to a new address
-@@ -4269,6 +4315,41 @@ void copy_user_huge_page(struct page *dst, struct page 
*src,
+@@ -4270,6 +4316,41 @@ void copy_user_huge_page(struct page *dst, struct page 
*src,
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
  
@@ -15548,14 +15609,14 @@ index 769a67a..b67a1ab 100644
  
        return pages;
 diff --git a/mm/vmalloc.c b/mm/vmalloc.c
-index aa3891e..5c756384 100644
+index aa3891e..9b8e1ef 100644
 --- a/mm/vmalloc.c
 +++ b/mm/vmalloc.c
 @@ -191,6 +191,8 @@ static int vmap_page_range_noflush(unsigned long start, 
unsigned long end,
                        return err;
        } while (pgd++, addr = next, addr != end);
  
-+      __ipipe_pin_range_globally(start, end);
++      __ipipe_pin_mapping_globally(start, end);
 + 
        return nr;
  }
diff --git a/kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-3.patch 
b/kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-5.patch
similarity index 98%
rename from kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-3.patch
rename to kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-5.patch
index 11a9917..757ae74 100644
--- a/kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-3.patch
+++ b/kernel/cobalt/arch/x86/patches/ipipe-core-3.18.20-x86-5.patch
@@ -198,18 +198,10 @@ index 61fd18b..43d7fe7 100644
  static inline void debug_stack_usage_inc(void)
  {
 diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
-index a94b82e..e185603 100644
+index a94b82e..39fa15d 100644
 --- a/arch/x86/include/asm/desc.h
 +++ b/arch/x86/include/asm/desc.h
-@@ -4,6 +4,7 @@
- #include <asm/desc_defs.h>
- #include <asm/ldt.h>
- #include <asm/mmu.h>
-+#include <asm/hw_irq.h>
- 
- #include <linux/smp.h>
- #include <linux/percpu.h>
-@@ -376,11 +377,16 @@ static inline void _set_gate(int gate, unsigned type, 
void *addr,
+@@ -376,11 +376,16 @@ static inline void _set_gate(int gate, unsigned type, 
void *addr,
   * Pentium F0 0F bugfix can have resulted in the mapped
   * IDT being write-protected.
   */
@@ -227,7 +219,14 @@ index a94b82e..e185603 100644
                _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\
                                0, 0, __KERNEL_CS);                     \
        } while (0)
-@@ -392,6 +398,13 @@ extern unsigned long used_vectors[];
+@@ -389,9 +394,20 @@ extern int first_system_vector;
+ /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
+ extern unsigned long used_vectors[];
+ 
++#ifdef CONFIG_IPIPE
++extern int vector_irq[NR_VECTORS];
++#endif
++
  static inline void alloc_system_vector(int vector)
  {
        if (!test_bit(vector, used_vectors)) {
@@ -241,7 +240,7 @@ index a94b82e..e185603 100644
                set_bit(vector, used_vectors);
                if (first_system_vector > vector)
                        first_system_vector = vector;
-@@ -400,6 +413,12 @@ static inline void alloc_system_vector(int vector)
+@@ -400,6 +416,12 @@ static inline void alloc_system_vector(int vector)
        }
  }
  
@@ -254,7 +253,7 @@ index a94b82e..e185603 100644
  #define alloc_intr_gate(n, addr)                              \
        do {                                                    \
                alloc_system_vector(n);                         \
-@@ -445,7 +464,7 @@ static inline void set_system_intr_gate_ist(int n, void 
*addr, unsigned ist)
+@@ -445,7 +467,7 @@ static inline void set_system_intr_gate_ist(int n, void 
*addr, unsigned ist)
        _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
  }
  
@@ -374,6 +373,18 @@ index 4615906..fcb4fb6 100644
  #endif
  
  extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);
+diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
+index ed8089d..fcc288e 100644
+--- a/arch/x86/include/asm/i387.h
++++ b/arch/x86/include/asm/i387.h
+@@ -21,6 +21,7 @@ struct user_i387_struct;
+ extern int init_fpu(struct task_struct *child);
+ extern void fpu_finit(struct fpu *fpu);
+ extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
++extern void __math_state_restore(struct task_struct *tsk);
+ extern void math_state_restore(void);
+ 
+ extern bool irq_fpu_usable(void);
 diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
 index ccffa53..f02e9f6 100644
 --- a/arch/x86/include/asm/i8259.h
@@ -438,7 +449,7 @@ index 615fa90..e0a62ab 100644
  extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
 diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h
 new file mode 100644
-index 0000000..68af8b7
+index 0000000..07859a5
 --- /dev/null
 +++ b/arch/x86/include/asm/ipipe.h
 @@ -0,0 +1,118 @@
@@ -468,7 +479,7 @@ index 0000000..68af8b7
 +
 +#ifdef CONFIG_IPIPE
 +
-+#define IPIPE_CORE_RELEASE    3
++#define IPIPE_CORE_RELEASE    5
 +
 +struct ipipe_domain;
 +struct pt_regs;
@@ -1703,7 +1714,7 @@ index de918c4..21d6c77 100644
  
  static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
 diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
-index 1183d54..595a4f3 100644
+index 1183d54..a513d60 100644
 --- a/arch/x86/kernel/apic/io_apic.c
 +++ b/arch/x86/kernel/apic/io_apic.c
 @@ -82,8 +82,8 @@
@@ -1767,7 +1778,7 @@ index 1183d54..595a4f3 100644
  }
  
  /*
-@@ -621,18 +628,28 @@ void native_eoi_ioapic_pin(int apic, int pin, int vector)
+@@ -621,15 +628,21 @@ void native_eoi_ioapic_pin(int apic, int pin, int vector)
        }
  }
  
@@ -1783,8 +1794,6 @@ index 1183d54..595a4f3 100644
                                               cfg->vector);
 +}
 +
-+#if !defined(CONFIG_IPIPE) || defined(CONFIG_SMP)
-+
 +void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
 +{
 +      unsigned long flags;
@@ -1794,12 +1803,7 @@ index 1183d54..595a4f3 100644
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
  }
  
-+#endif /* !CONFIG_IPIPE || CONFIG_SMP */
-+
- static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
- {
-       struct IO_APIC_route_entry entry;
-@@ -1395,8 +1412,19 @@ void __setup_vector_irq(int cpu)
+@@ -1395,8 +1408,19 @@ void __setup_vector_irq(int cpu)
                vector = cfg->vector;
                per_cpu(vector_irq, cpu)[vector] = irq;
        }
@@ -1819,7 +1823,7 @@ index 1183d54..595a4f3 100644
                irq = per_cpu(vector_irq, cpu)[vector];
                if (irq <= VECTOR_UNDEFINED)
                        continue;
-@@ -1480,6 +1508,19 @@ int native_setup_ioapic_entry(int irq, struct 
IO_APIC_route_entry *entry,
+@@ -1480,6 +1504,19 @@ int native_setup_ioapic_entry(int irq, struct 
IO_APIC_route_entry *entry,
        return 0;
  }
  
@@ -1839,7 +1843,7 @@ index 1183d54..595a4f3 100644
  static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,
                                struct io_apic_irq_attr *attr)
  {
-@@ -1517,7 +1558,7 @@ static void setup_ioapic_irq(unsigned int irq, struct 
irq_cfg *cfg,
+@@ -1517,7 +1554,7 @@ static void setup_ioapic_irq(unsigned int irq, struct 
irq_cfg *cfg,
  
        ioapic_register_intr(irq, cfg, attr->trigger);
        if (irq < nr_legacy_irqs())
@@ -1848,7 +1852,7 @@ index 1183d54..595a4f3 100644
  
        ioapic_write_entry(attr->ioapic, attr->ioapic_pin, entry);
  }
-@@ -2240,11 +2281,12 @@ static unsigned int startup_ioapic_irq(struct irq_data 
*data)
+@@ -2240,11 +2277,12 @@ static unsigned int startup_ioapic_irq(struct irq_data 
*data)
  
        raw_spin_lock_irqsave(&ioapic_lock, flags);
        if (irq < nr_legacy_irqs()) {
@@ -1862,7 +1866,7 @@ index 1183d54..595a4f3 100644
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
  
        return was_pending;
-@@ -2299,7 +2341,8 @@ asmlinkage __visible void 
smp_irq_move_cleanup_interrupt(void)
+@@ -2299,7 +2337,8 @@ asmlinkage __visible void 
smp_irq_move_cleanup_interrupt(void)
        exit_idle();
  
        me = smp_processor_id();
@@ -1872,7 +1876,7 @@ index 1183d54..595a4f3 100644
                int irq;
                unsigned int irr;
                struct irq_desc *desc;
-@@ -2460,14 +2503,16 @@ int native_ioapic_set_affinity(struct irq_data *data,
+@@ -2460,14 +2499,16 @@ int native_ioapic_set_affinity(struct irq_data *data,
  
  static void ack_apic_edge(struct irq_data *data)
  {
@@ -1891,7 +1895,7 @@ index 1183d54..595a4f3 100644
  static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
  {
        struct irq_pin_list *entry;
-@@ -2495,7 +2540,7 @@ static inline bool ioapic_irqd_mask(struct irq_data 
*data, struct irq_cfg *cfg)
+@@ -2495,7 +2536,7 @@ static inline bool ioapic_irqd_mask(struct irq_data 
*data, struct irq_cfg *cfg)
  {
        /* If we are moving the irq we need to mask it */
        if (unlikely(irqd_is_setaffinity_pending(data))) {
@@ -1900,7 +1904,7 @@ index 1183d54..595a4f3 100644
                return true;
        }
        return false;
-@@ -2533,7 +2578,7 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
+@@ -2533,7 +2574,7 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
                 */
                if (!io_apic_level_ack_pending(cfg))
                        irq_move_masked_irq(data);
@@ -1909,7 +1913,7 @@ index 1183d54..595a4f3 100644
        }
  }
  #else
-@@ -2547,12 +2592,46 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
+@@ -2547,12 +2588,46 @@ static inline void ioapic_irqd_unmask(struct irq_data 
*data,
  }
  #endif
  
@@ -1957,7 +1961,7 @@ index 1183d54..595a4f3 100644
  
        irq_complete_move(cfg);
        masked = ioapic_irqd_mask(data, cfg);
-@@ -2612,8 +2691,50 @@ static void ack_apic_level(struct irq_data *data)
+@@ -2612,8 +2687,50 @@ static void ack_apic_level(struct irq_data *data)
        }
  
        ioapic_irqd_unmask(data, cfg, masked);
@@ -1991,8 +1995,8 @@ index 1183d54..595a4f3 100644
 +      __mask_ioapic(cfg);
 +      raw_spin_unlock(&ioapic_lock);
 +      ack_apic_level(data);
-+}
-+
+ }
+ 
 +static void release_ioapic_irq(struct irq_data *data)
 +{
 +      struct irq_cfg *cfg = data->chip_data;
@@ -2001,14 +2005,14 @@ index 1183d54..595a4f3 100644
 +      raw_spin_lock_irqsave(&ioapic_lock, flags);
 +      __unmask_ioapic(cfg);
 +      raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- }
- 
++}
++
 +#endif        /* CONFIG_IPIPE */
 +
  static struct irq_chip ioapic_chip __read_mostly = {
        .name                   = "IO-APIC",
        .irq_startup            = startup_ioapic_irq,
-@@ -2623,6 +2744,13 @@ static struct irq_chip ioapic_chip __read_mostly = {
+@@ -2623,6 +2740,13 @@ static struct irq_chip ioapic_chip __read_mostly = {
        .irq_eoi                = ack_apic_level,
        .irq_set_affinity       = native_ioapic_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2022,7 +2026,7 @@ index 1183d54..595a4f3 100644
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
  };
  
-@@ -2654,23 +2782,29 @@ static inline void init_IO_APIC_traps(void)
+@@ -2654,23 +2778,29 @@ static inline void init_IO_APIC_traps(void)
  
  static void mask_lapic_irq(struct irq_data *data)
  {
@@ -2055,7 +2059,7 @@ index 1183d54..595a4f3 100644
  }
  
  static struct irq_chip lapic_chip __read_mostly = {
-@@ -2678,6 +2812,9 @@ static struct irq_chip lapic_chip __read_mostly = {
+@@ -2678,6 +2808,9 @@ static struct irq_chip lapic_chip __read_mostly = {
        .irq_mask       = mask_lapic_irq,
        .irq_unmask     = unmask_lapic_irq,
        .irq_ack        = ack_lapic_irq,
@@ -2065,7 +2069,7 @@ index 1183d54..595a4f3 100644
  };
  
  static void lapic_register_intr(int irq)
-@@ -2776,7 +2913,7 @@ static inline void __init check_timer(void)
+@@ -2776,7 +2909,7 @@ static inline void __init check_timer(void)
        /*
         * get/set the timer IRQ vector:
         */
@@ -2074,7 +2078,7 @@ index 1183d54..595a4f3 100644
        assign_irq_vector(0, cfg, apic->target_cpus());
  
        /*
-@@ -2833,7 +2970,7 @@ static inline void __init check_timer(void)
+@@ -2833,7 +2966,7 @@ static inline void __init check_timer(void)
                        int idx;
                        idx = find_irq_entry(apic1, pin1, mp_INT);
                        if (idx != -1 && irq_trigger(idx))
@@ -2083,7 +2087,7 @@ index 1183d54..595a4f3 100644
                }
                if (timer_irq_works()) {
                        if (disable_timer_pin_1 > 0)
-@@ -2865,7 +3002,7 @@ static inline void __init check_timer(void)
+@@ -2865,7 +2998,7 @@ static inline void __init check_timer(void)
                 * Cleanup, just in case ...
                 */
                local_irq_disable();
@@ -2092,7 +2096,7 @@ index 1183d54..595a4f3 100644
                clear_IO_APIC_pin(apic2, pin2);
                apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
        }
-@@ -2874,6 +3011,10 @@ static inline void __init check_timer(void)
+@@ -2874,6 +3007,10 @@ static inline void __init check_timer(void)
                    "...trying to set up timer as Virtual Wire IRQ...\n");
  
        lapic_register_intr(0);
@@ -2103,7 +2107,7 @@ index 1183d54..595a4f3 100644
        apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector);     /* Fixed mode */
        legacy_pic->unmask(0);
  
-@@ -2882,7 +3023,7 @@ static inline void __init check_timer(void)
+@@ -2882,7 +3019,7 @@ static inline void __init check_timer(void)
                goto out;
        }
        local_irq_disable();
@@ -2112,7 +2116,7 @@ index 1183d54..595a4f3 100644
        apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
        apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
  
-@@ -3174,6 +3315,9 @@ static struct irq_chip msi_chip = {
+@@ -3174,6 +3311,9 @@ static struct irq_chip msi_chip = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = msi_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2122,7 +2126,7 @@ index 1183d54..595a4f3 100644
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
  };
  
-@@ -3273,6 +3417,9 @@ static struct irq_chip dmar_msi_type = {
+@@ -3273,6 +3413,9 @@ static struct irq_chip dmar_msi_type = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = dmar_msi_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2132,7 +2136,7 @@ index 1183d54..595a4f3 100644
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
  };
  
-@@ -3324,6 +3471,9 @@ static struct irq_chip hpet_msi_type = {
+@@ -3324,6 +3467,9 @@ static struct irq_chip hpet_msi_type = {
        .irq_ack = ack_apic_edge,
        .irq_set_affinity = hpet_msi_set_affinity,
        .irq_retrigger = ioapic_retrigger_irq,
@@ -2142,7 +2146,7 @@ index 1183d54..595a4f3 100644
        .flags = IRQCHIP_SKIP_SET_WAKE,
  };
  
-@@ -3388,6 +3538,9 @@ static struct irq_chip ht_irq_chip = {
+@@ -3388,6 +3534,9 @@ static struct irq_chip ht_irq_chip = {
        .irq_ack                = ack_apic_edge,
        .irq_set_affinity       = ht_set_affinity,
        .irq_retrigger          = ioapic_retrigger_irq,
@@ -2152,7 +2156,7 @@ index 1183d54..595a4f3 100644
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
  };
  
-@@ -3631,6 +3784,18 @@ int acpi_get_override_irq(u32 gsi, int *trigger, int 
*polarity)
+@@ -3631,6 +3780,18 @@ int acpi_get_override_irq(u32 gsi, int *trigger, int 
*polarity)
        return 0;
  }
  
@@ -3298,7 +3302,7 @@ index 319bcb9..49cc3ff 100644
  
        printk(KERN_INFO "HPET: %d timers in total, %d timers will be used for 
per-cpu timer\n",
 diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
-index 8d6e954..6cdfefe 100644
+index 8d6e954..e06eb01 100644
 --- a/arch/x86/kernel/i387.c
 +++ b/arch/x86/kernel/i387.c
 @@ -73,7 +73,9 @@ EXPORT_SYMBOL(irq_fpu_usable);
@@ -3311,7 +3315,7 @@ index 8d6e954..6cdfefe 100644
        if (__thread_has_fpu(me)) {
                __thread_clear_has_fpu(me);
                __save_init_fpu(me);
-@@ -82,6 +84,7 @@ void __kernel_fpu_begin(void)
+@@ -82,11 +84,15 @@ void __kernel_fpu_begin(void)
                this_cpu_write(fpu_owner_task, NULL);
                clts();
        }
@@ -3319,6 +3323,27 @@ index 8d6e954..6cdfefe 100644
  }
  EXPORT_SYMBOL(__kernel_fpu_begin);
  
+ void __kernel_fpu_end(void)
+ {
++      unsigned long flags;
++
++      flags = hard_cond_local_irq_save();
+       if (use_eager_fpu()) {
+               /*
+                * For eager fpu, most the time, tsk_used_math() is true.
+@@ -96,10 +102,11 @@ void __kernel_fpu_end(void)
+                * actions, so we don't need to restore the math here.
+                */
+               if (likely(tsk_used_math(current)))
+-                      math_state_restore();
++                      __math_state_restore(current);
+       } else {
+               stts();
+       }
++      hard_cond_local_irq_restore(flags);
+ }
+ EXPORT_SYMBOL(__kernel_fpu_end);
+ 
 diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
 index f2b96de..51e9d08 100644
 --- a/arch/x86/kernel/i8253.c
@@ -4267,7 +4292,7 @@ index 668d8f2..913c3c7 100644
        while (!cpu_online(cpu)) {
                cpu_relax();
 diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
-index 07ab8e9..617f07c 100644
+index 07ab8e9..6e9aa67 100644
 --- a/arch/x86/kernel/traps.c
 +++ b/arch/x86/kernel/traps.c
 @@ -221,9 +221,9 @@ static void do_error_trap(struct pt_regs *regs, long 
error_code, char *str,
@@ -4416,7 +4441,31 @@ index 07ab8e9..617f07c 100644
  asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void)
  {
  }
-@@ -689,6 +728,7 @@ asmlinkage __visible void __attribute__((weak)) 
smp_threshold_interrupt(void)
+@@ -676,6 +715,23 @@ asmlinkage __visible void __attribute__((weak)) 
smp_threshold_interrupt(void)
+ {
+ }
+ 
++void __math_state_restore(struct task_struct *tsk)
++{
++      __thread_fpu_begin(tsk);
++
++      /*
++       * Paranoid restore. send a SIGSEGV if we fail to restore the state.
++       */
++      if (unlikely(restore_fpu_checking(tsk))) {
++              drop_init_fpu(tsk);
++              hard_cond_local_irq_enable();
++              force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk);
++              return;
++      }
++
++      tsk->thread.fpu_counter++;
++}
++
+ /*
+  * 'math_state_restore()' saves the current math information in the
+  * old math state array, and gets the new ones from the current task
+@@ -689,6 +745,7 @@ asmlinkage __visible void __attribute__((weak)) 
smp_threshold_interrupt(void)
  void math_state_restore(void)
  {
        struct task_struct *tsk = current;
@@ -4424,24 +4473,24 @@ index 07ab8e9..617f07c 100644
  
        if (!tsk_used_math(tsk)) {
                local_irq_enable();
-@@ -705,6 +745,7 @@ void math_state_restore(void)
+@@ -705,23 +762,14 @@ void math_state_restore(void)
                local_irq_disable();
        }
  
+-      __thread_fpu_begin(tsk);
+-
+-      /*
+-       * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+-       */
+-      if (unlikely(restore_fpu_checking(tsk))) {
+-              drop_init_fpu(tsk);
+-              force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk);
+-              return;
+-      }
+-
+-      tsk->thread.fpu_counter++;
 +      flags = hard_cond_local_irq_save();
-       __thread_fpu_begin(tsk);
- 
-       /*
-@@ -712,16 +753,18 @@ void math_state_restore(void)
-        */
-       if (unlikely(restore_fpu_checking(tsk))) {
-               drop_init_fpu(tsk);
-+              hard_cond_local_irq_enable();
-               force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk);
-               return;
-       }
- 
-       tsk->thread.fpu_counter++;
++      __math_state_restore(tsk);
 +      hard_cond_local_irq_restore(flags);
  }
  EXPORT_SYMBOL_GPL(math_state_restore);
@@ -4453,7 +4502,7 @@ index 07ab8e9..617f07c 100644
  {
        enum ctx_state prev_state;
  
-@@ -746,10 +789,16 @@ do_device_not_available(struct pt_regs *regs, long 
error_code)
+@@ -746,10 +794,16 @@ do_device_not_available(struct pt_regs *regs, long 
error_code)
  #endif
        exception_exit(prev_state);
  }
@@ -4471,7 +4520,7 @@ index 07ab8e9..617f07c 100644
  {
        siginfo_t info;
        enum ctx_state prev_state;
-@@ -768,14 +817,24 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, 
long error_code)
+@@ -768,14 +822,24 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, 
long error_code)
        }
        exception_exit(prev_state);
  }
@@ -5360,8 +5409,27 @@ index c5029c1..2d68014 100644
        select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
        select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
        help
+diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
+index 74a1767..7cf4766 100644
+--- a/drivers/iommu/irq_remapping.c
++++ b/drivers/iommu/irq_remapping.c
+@@ -366,12 +366,12 @@ void panic_if_irq_remap(const char *msg)
+ 
+ static void ir_ack_apic_edge(struct irq_data *data)
+ {
+-      ack_APIC_irq();
++      __ack_APIC_irq();
+ }
+ 
+ static void ir_ack_apic_level(struct irq_data *data)
+ {
+-      ack_APIC_irq();
++      __ack_APIC_irq();
+       eoi_ioapic_irq(data->irq, data->chip_data);
+ }
+ 
 diff --git a/drivers/tty/serial/8250/8250_core.c 
b/drivers/tty/serial/8250/8250_core.c
-index e5c31ea..8dce875 100644
+index e5c31ea..8dce8751 100644
 --- a/drivers/tty/serial/8250/8250_core.c
 +++ b/drivers/tty/serial/8250/8250_core.c
 @@ -3480,6 +3480,84 @@ static int serial8250_resume(struct platform_device 
*dev)
@@ -9283,10 +9351,10 @@ index 0000000..797a849
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..0320453
+index 0000000..d7c8934
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1917 @@
+@@ -0,0 +1,1916 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -11025,11 +11093,10 @@ index 0000000..0320453
 +       * currently stalled, in which case preemption would be
 +       * disabled, and no migration could occur.
 +       */
-+      if (this_domain == ipipe_root_domain) {
-+              p = raw_cpu_ptr(&ipipe_percpu.root);
-+              if (test_bit(IPIPE_STALL_FLAG, &p->status) || preempt_count())
-+                      goto out;
-+      }
++
++      p = raw_cpu_ptr(&ipipe_percpu.root);
++      if (!preemptible())
++              goto out;
 +      /*
 +       * Our caller may end up accessing the wrong per-cpu variable
 +       * instance due to CPU migration; tell it to complain about
@@ -11206,10 +11273,10 @@ index 0000000..0320453
 +#endif
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..354bf29
+index 0000000..143f9e6
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,496 @@
+@@ -0,0 +1,497 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -11577,6 +11644,7 @@ index 0000000..354bf29
 +              timer->real_set_next_event = evtdev->set_next_event;
 +              evtdev->mult = 1;
 +              evtdev->shift = 0;
++              evtdev->max_delta_ns = UINT_MAX;
 +              evtdev->set_mode = emumode;
 +              evtdev->set_next_event = emutick;
 +              evtdev->ipipe_stolen = 1;
diff --git a/kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-1.patch 
b/kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-2.patch
similarity index 99%
rename from kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-1.patch
rename to kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-2.patch
index 32ade4e..5cc2396 100644
--- a/kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-1.patch
+++ b/kernel/cobalt/arch/x86/patches/ipipe-core-4.1.18-x86-2.patch
@@ -434,7 +434,7 @@ index 615fa90..e0a62ab 100644
  extern void default_send_IPI_mask_sequence_phys(const struct cpumask *mask,
 diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h
 new file mode 100644
-index 0000000..9425e5e
+index 0000000..f01ff21
 --- /dev/null
 +++ b/arch/x86/include/asm/ipipe.h
 @@ -0,0 +1,112 @@
@@ -464,7 +464,7 @@ index 0000000..9425e5e
 +
 +#ifdef CONFIG_IPIPE
 +
-+#define IPIPE_CORE_RELEASE    1
++#define IPIPE_CORE_RELEASE    2
 +
 +struct ipipe_domain;
 +struct pt_regs;
@@ -1221,9 +1221,18 @@ index b77f5ed..e532ef5 100644
 +#endif /* __ASSEMBLY__ */
  #endif
 diff --git a/arch/x86/include/asm/mmu_context.h 
b/arch/x86/include/asm/mmu_context.h
-index 73e38f1..2a48bb9 100644
+index 73e38f1..4ceb737 100644
 --- a/arch/x86/include/asm/mmu_context.h
 +++ b/arch/x86/include/asm/mmu_context.h
+@@ -74,7 +74,7 @@ static inline void load_mm_ldt(struct mm_struct *mm)
+       else
+               clear_LDT();
+ 
+-      DEBUG_LOCKS_WARN_ON(preemptible());
++      DEBUG_LOCKS_WARN_ON(preemptible() && !hard_irqs_disabled());
+ }
+ 
+ /*
 @@ -92,11 +92,14 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, 
struct task_struct *tsk)
  #endif
  }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to