Module: xenomai-2.6
Branch: master
Commit: 624e7247629515ffd3d6b3fd4166a9cfef6dc5ed
URL:    
http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=624e7247629515ffd3d6b3fd4166a9cfef6dc5ed

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Jan 22 12:02:01 2013 +0100

blackfin: upgrade I-pipe support

---

 ...-2.patch => ipipe-core-3.2.21-blackfin-4.patch} |  115 ++++--
 ...n-2.patch => ipipe-core-3.4.6-blackfin-4.patch} |  171 ++++++--
 ...n-2.patch => ipipe-core-3.5.7-blackfin-3.patch} |  443 +++++++++++---------
 3 files changed, 444 insertions(+), 285 deletions(-)

diff --git a/ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-2.patch 
b/ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-4.patch
similarity index 99%
rename from ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-2.patch
rename to ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-4.patch
index c2ed3b5..692f4b9 100644
--- a/ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-2.patch
+++ b/ksrc/arch/blackfin/patches/ipipe-core-3.2.21-blackfin-4.patch
@@ -12,7 +12,7 @@ index abe5a9e..ff2f9f7 100644
  
  comment "Processor and Board Settings"
 diff --git a/arch/blackfin/include/asm/ipipe.h 
b/arch/blackfin/include/asm/ipipe.h
-index 17b5e92..3a0c506 100644
+index 17b5e92..fb626c4 100644
 --- a/arch/blackfin/include/asm/ipipe.h
 +++ b/arch/blackfin/include/asm/ipipe.h
 @@ -28,7 +28,7 @@
@@ -32,7 +32,7 @@ index 17b5e92..3a0c506 100644
 -#define IPIPE_MAJOR_NUMBER    1
 -#define IPIPE_MINOR_NUMBER    16
 -#define IPIPE_PATCH_NUMBER    1
-+#define IPIPE_CORE_RELEASE    2
++#define IPIPE_CORE_RELEASE    4
  
  #ifdef CONFIG_SMP
  #error "I-pipe/blackfin: SMP not implemented"
@@ -1861,10 +1861,10 @@ index e6bb36a..898a91a 100644
  
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..f282637
+index 0000000..b8e628e
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,399 @@
+@@ -0,0 +1,419 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -1935,6 +1935,7 @@ index 0000000..f282637
 +void __ipipe_reenter_root(void);
 +
 +int __ipipe_disable_ondemand_mappings(struct task_struct *p);
++
 +int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma);
 +
 +#ifdef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
@@ -2167,31 +2168,50 @@ index 0000000..f282637
 +
 +static inline void ipipe_enable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
 +
-+      if (WARN_ON_ONCE(chip->irq_unmask == NULL))
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
 +              return;
 +
-+      chip->irq_unmask(&desc->irq_data);
++      chip = irq_desc_get_chip(desc);
++
++      if (WARN_ON_ONCE(chip->irq_enable == NULL && chip->irq_unmask == NULL))
++              return;
++
++      if (chip->irq_enable)
++              chip->irq_enable(&desc->irq_data);
++      else
++              chip->irq_unmask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_disable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
++
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
++              return;
++
++      chip = irq_desc_get_chip(desc);
 +
-+      if (WARN_ON_ONCE(chip->irq_mask == NULL))
++      if (WARN_ON_ONCE(chip->irq_disable == NULL && chip->irq_mask == NULL))
 +              return;
 +
-+      chip->irq_mask(&desc->irq_data);
++      if (chip->irq_disable)
++              chip->irq_disable(&desc->irq_data);
++      else
++              chip->irq_mask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_end_irq(unsigned int irq)
 +{
 +      struct irq_desc *desc = irq_to_desc(irq);
 +
-+      desc->ipipe_end(irq, desc);
++      if (desc)
++              desc->ipipe_end(irq, desc);
 +}
 +
 +static inline int ipipe_chained_irq_p(unsigned int irq)
@@ -4922,10 +4942,10 @@ index 0000000..1147bf4
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..1f32d4a
+index 0000000..19dfead
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1706 @@
+@@ -0,0 +1,1729 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -5990,25 +6010,50 @@ index 0000000..1f32d4a
 +{
 +}
 +
++#ifdef CONFIG_IPIPE_LEGACY
++
++static inline void complete_domain_migration(void) /* hw IRQs off */
++{
++      current->state &= ~TASK_HARDENING;
++}
++
++#else /* !CONFIG_IPIPE_LEGACY */
++
 +static void complete_domain_migration(void) /* hw IRQs off */
 +{
++      struct ipipe_percpu_domain_data *p;
 +      struct ipipe_percpu_data *pd;
-+      struct task_struct *p;
++      struct task_struct *t;
 +
++      ipipe_root_only();
 +      pd = __this_cpu_ptr(&ipipe_percpu);
-+      p = pd->task_hijacked;
-+      if (p) {
-+              p->state &= ~TASK_HARDENING;
-+              pd->task_hijacked = NULL;
-+              ipipe_migration_hook(p);
-+      }
++      t = pd->task_hijacked;
++      if (t == NULL)
++              return;
++
++      pd->task_hijacked = NULL;
++      t->state &= ~TASK_HARDENING;
++      if (t->state != TASK_INTERRUPTIBLE)
++              /* Migration aborted (by signal). */
++              return;
++
++      p = ipipe_this_cpu_head_context();
++      IPIPE_WARN_ONCE(test_bit(IPIPE_STALL_FLAG, &p->status));
++      /*
++       * hw IRQs are disabled, but the completion hook assumes the
++       * head domain is logically stalled: fix it up.
++       */
++      __set_bit(IPIPE_STALL_FLAG, &p->status);
++      ipipe_migration_hook(t);
++      __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +}
 +
++#endif /* !CONFIG_IPIPE_LEGACY */
++
 +void __ipipe_complete_domain_migration(void)
 +{
 +      unsigned long flags;
 +
-+      ipipe_root_only();
 +      flags = hard_local_irq_save();
 +      complete_domain_migration();
 +      hard_local_irq_restore(flags);
@@ -6023,12 +6068,10 @@ index 0000000..1f32d4a
 +      hard_local_irq_disable();
 +#endif
 +      x = __ipipe_root_p;
-+
-+#ifdef CONFIG_IPIPE_LEGACY
-+      current->state &= ~TASK_HARDENING;
-+#else
-+      complete_domain_migration();
-+#endif        /* !CONFIG_IPIPE_LEGACY */
++#ifndef CONFIG_IPIPE_LEGACY
++      if (x)
++#endif
++              complete_domain_migration();
 +
 +#ifndef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
 +      if (x)
@@ -6634,10 +6677,10 @@ index 0000000..1f32d4a
 +EXPORT_SYMBOL_GPL(__ipipe_post_work_root);
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..a2b8672
+index 0000000..d7d129a
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,383 @@
+@@ -0,0 +1,393 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -6899,6 +6942,7 @@ index 0000000..a2b8672
 +{
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +      unsigned long flags;
 +      int steal, rc;
 +
@@ -6939,6 +6983,10 @@ index 0000000..a2b8672
 +  done:
 +      ipipe_critical_exit(flags);
 +
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
++              ipipe_enable_irq(timer->irq);
++
 +      return rc;
 +}
 +
@@ -6946,11 +6994,16 @@ index 0000000..a2b8672
 +{
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +      unsigned long flags;
 +
 +      timer = per_cpu(percpu_timer, cpu);
 +      evtdev = timer->host_timer;
 +
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
++              ipipe_disable_irq(timer->irq);
++
 +      flags = ipipe_critical_enter(NULL);
 +
 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
diff --git a/ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-2.patch 
b/ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-4.patch
similarity index 98%
rename from ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-2.patch
rename to ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-4.patch
index dc655c0..3788f6e 100644
--- a/ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-2.patch
+++ b/ksrc/arch/blackfin/patches/ipipe-core-3.4.6-blackfin-4.patch
@@ -12,7 +12,7 @@ index 373a690..e79db84 100644
  
  comment "Processor and Board Settings"
 diff --git a/arch/blackfin/include/asm/ipipe.h 
b/arch/blackfin/include/asm/ipipe.h
-index 17b5e92..50d41b9 100644
+index 17b5e92..a3aa223 100644
 --- a/arch/blackfin/include/asm/ipipe.h
 +++ b/arch/blackfin/include/asm/ipipe.h
 @@ -28,7 +28,7 @@
@@ -32,7 +32,7 @@ index 17b5e92..50d41b9 100644
 -#define IPIPE_MAJOR_NUMBER    1
 -#define IPIPE_MINOR_NUMBER    16
 -#define IPIPE_PATCH_NUMBER    1
-+#define IPIPE_CORE_RELEASE    2
++#define IPIPE_CORE_RELEASE    4
  
  #ifdef CONFIG_SMP
  #error "I-pipe/blackfin: SMP not implemented"
@@ -1516,17 +1516,45 @@ index 78a666d..20e9852 100644
          CPU idle is a generic framework for supporting software-controlled
          idle processor power management.  It includes modular cross-platform
 diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
-index d537431..cb1e915 100644
+index d537431..bf54642 100644
 --- a/drivers/tty/serial/8250/8250.c
 +++ b/drivers/tty/serial/8250/8250.c
-@@ -3097,6 +3097,56 @@ static int serial8250_resume(struct platform_device 
*dev)
+@@ -3097,6 +3097,84 @@ static int serial8250_resume(struct platform_device 
*dev)
        return 0;
  }
  
 +#if defined(CONFIG_IPIPE_DEBUG) && defined(CONFIG_SERIAL_8250_CONSOLE)
 +
++static IPIPE_DEFINE_SPINLOCK(ipipe_8250_lock);
++
 +#include <stdarg.h>
 +
++static void wait_for_xmitr_nodelay(struct uart_8250_port *up, int bits)
++{
++      unsigned int status, tmout = 10000;
++
++      for (;;) {
++              status = serial_in(up, UART_LSR);
++
++              up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
++
++              if ((status & bits) == bits)
++                      break;
++              if (--tmout == 0)
++                      break;
++              cpu_relax();
++      }
++}
++
++static void serial8250_console_putchar_nodelay(struct uart_port *port, int ch)
++{
++      struct uart_8250_port *up =
++              container_of(port, struct uart_8250_port, port);
++
++      wait_for_xmitr_nodelay(up, UART_LSR_THRE);
++      serial_port_out(port, UART_TX, ch);
++}
++
 +void __weak __ipipe_serial_debug(const char *fmt, ...)
 +{
 +        struct uart_8250_port *up = &serial8250_ports[0];
@@ -1547,7 +1575,7 @@ index d537431..cb1e915 100644
 +
 +        touch_nmi_watchdog();
 +
-+        flags = hard_local_irq_save();
++        spin_lock_irqsave(&ipipe_8250_lock, flags);
 +
 +        /*
 +         *      First save the IER then disable the interrupts
@@ -1559,16 +1587,16 @@ index d537431..cb1e915 100644
 +        else
 +                serial_out(up, UART_IER, 0);
 +
-+        uart_console_write(&up->port, buf, count, serial8250_console_putchar);
++        uart_console_write(&up->port, buf, count, 
serial8250_console_putchar_nodelay);
 +
 +        /*
 +         *      Finally, wait for transmitter to become empty
 +         *      and restore the IER
 +         */
-+        wait_for_xmitr(up, BOTH_EMPTY);
++        wait_for_xmitr_nodelay(up, BOTH_EMPTY);
 +        serial_out(up, UART_IER, ier);
 +
-+        hard_local_irq_restore(flags);
++        spin_unlock_irqrestore(&ipipe_8250_lock, flags);
 +}
 +
 +#endif
@@ -1906,10 +1934,10 @@ index e6bb36a..898a91a 100644
  
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..a495bde
+index 0000000..ac0d19d
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,406 @@
+@@ -0,0 +1,426 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -1980,6 +2008,7 @@ index 0000000..a495bde
 +void __ipipe_reenter_root(void);
 +
 +int __ipipe_disable_ondemand_mappings(struct task_struct *p);
++
 +int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma);
 +
 +#ifdef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
@@ -2220,31 +2249,50 @@ index 0000000..a495bde
 +
 +static inline void ipipe_enable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
 +
-+      if (WARN_ON_ONCE(chip->irq_unmask == NULL))
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
 +              return;
 +
-+      chip->irq_unmask(&desc->irq_data);
++      chip = irq_desc_get_chip(desc);
++
++      if (WARN_ON_ONCE(chip->irq_enable == NULL && chip->irq_unmask == NULL))
++              return;
++
++      if (chip->irq_enable)
++              chip->irq_enable(&desc->irq_data);
++      else
++              chip->irq_unmask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_disable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
++
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
++              return;
 +
-+      if (WARN_ON_ONCE(chip->irq_mask == NULL))
++      chip = irq_desc_get_chip(desc);
++
++      if (WARN_ON_ONCE(chip->irq_disable == NULL && chip->irq_mask == NULL))
 +              return;
 +
-+      chip->irq_mask(&desc->irq_data);
++      if (chip->irq_disable)
++              chip->irq_disable(&desc->irq_data);
++      else
++              chip->irq_mask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_end_irq(unsigned int irq)
 +{
 +      struct irq_desc *desc = irq_to_desc(irq);
 +
-+      desc->ipipe_end(irq, desc);
++      if (desc)
++              desc->ipipe_end(irq, desc);
 +}
 +
 +static inline int ipipe_chained_irq_p(struct irq_desc *desc)
@@ -5067,10 +5115,10 @@ index 0000000..1147bf4
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..578468c
+index 0000000..d220c70
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1706 @@
+@@ -0,0 +1,1730 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -6135,25 +6183,50 @@ index 0000000..578468c
 +{
 +}
 +
++#ifdef CONFIG_IPIPE_LEGACY
++
++static inline void complete_domain_migration(void) /* hw IRQs off */
++{
++      current->state &= ~TASK_HARDENING;
++}
++
++#else /* !CONFIG_IPIPE_LEGACY */
++
 +static void complete_domain_migration(void) /* hw IRQs off */
 +{
++      struct ipipe_percpu_domain_data *p;
 +      struct ipipe_percpu_data *pd;
-+      struct task_struct *p;
++      struct task_struct *t;
 +
++      ipipe_root_only();
 +      pd = __this_cpu_ptr(&ipipe_percpu);
-+      p = pd->task_hijacked;
-+      if (p) {
-+              p->state &= ~TASK_HARDENING;
-+              pd->task_hijacked = NULL;
-+              ipipe_migration_hook(p);
-+      }
++      t = pd->task_hijacked;
++      if (t == NULL)
++              return;
++
++      pd->task_hijacked = NULL;
++      t->state &= ~TASK_HARDENING;
++      if (t->state != TASK_INTERRUPTIBLE)
++              /* Migration aborted (by signal). */
++              return;
++
++      p = ipipe_this_cpu_head_context();
++      IPIPE_WARN_ONCE(test_bit(IPIPE_STALL_FLAG, &p->status));
++      /*
++       * hw IRQs are disabled, but the completion hook assumes the
++       * head domain is logically stalled: fix it up.
++       */
++      __set_bit(IPIPE_STALL_FLAG, &p->status);
++      ipipe_migration_hook(t);
++      __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +}
 +
++#endif /* !CONFIG_IPIPE_LEGACY */
++
 +void __ipipe_complete_domain_migration(void)
 +{
 +      unsigned long flags;
 +
-+      ipipe_root_only();
 +      flags = hard_local_irq_save();
 +      complete_domain_migration();
 +      hard_local_irq_restore(flags);
@@ -6168,12 +6241,10 @@ index 0000000..578468c
 +      hard_local_irq_disable();
 +#endif
 +      x = __ipipe_root_p;
-+
-+#ifdef CONFIG_IPIPE_LEGACY
-+      current->state &= ~TASK_HARDENING;
-+#else
-+      complete_domain_migration();
-+#endif        /* !CONFIG_IPIPE_LEGACY */
++#ifndef CONFIG_IPIPE_LEGACY
++      if (x)
++#endif
++              complete_domain_migration();
 +
 +#ifndef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
 +      if (x)
@@ -6217,18 +6288,19 @@ index 0000000..578468c
 +      head->irqs[irq].handler(irq, head->irqs[irq].cookie);
 +      __ipipe_run_irqtail(irq);
 +      hard_local_irq_disable();
++      p = ipipe_this_cpu_head_context();
 +      __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +
 +      /* Are we still running in the head domain? */
 +      if (likely(__ipipe_current_context == p)) {
 +              /* Did we enter this code over the head domain? */
-+              if (old == p) {
++              if (old->domain == head) {
 +                      /* Yes, do immediate synchronization. */
 +                      if (__ipipe_ipending_p(p))
 +                              __ipipe_sync_stage();
 +                      return;
 +              }
-+              __ipipe_set_current_context(old);
++              __ipipe_set_current_context(ipipe_this_cpu_root_context());
 +      }
 +
 +      /*
@@ -6779,10 +6851,10 @@ index 0000000..578468c
 +EXPORT_SYMBOL_GPL(__ipipe_post_work_root);
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..9a076ab
+index 0000000..4281cb1
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,480 @@
+@@ -0,0 +1,483 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -7115,6 +7187,7 @@ index 0000000..9a076ab
 +{
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +      unsigned long flags;
 +      int steal, ret;
 +
@@ -7154,10 +7227,10 @@ index 0000000..9a076ab
 +  done:
 +      ipipe_critical_exit(flags);
 +
-+#ifdef CONFIG_GENERIC_CLOCKEVENTS
-+      if (evtdev && evtdev->mode == CLOCK_EVT_MODE_UNUSED)
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
 +              ipipe_enable_irq(timer->irq);
-+#endif
++
 +      return ret;
 +}
 +
@@ -7166,15 +7239,17 @@ index 0000000..9a076ab
 +      unsigned long __maybe_unused flags;
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +
 +      timer = per_cpu(percpu_timer, cpu);
 +      evtdev = timer->host_timer;
 +
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
++              ipipe_disable_irq(timer->irq);
++
 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
 +      if (evtdev) {
-+              if (evtdev->mode == CLOCK_EVT_MODE_UNUSED)
-+                      ipipe_disable_irq(timer->irq);
-+
 +              flags = ipipe_critical_enter(NULL);
 +
 +              if (evtdev->ipipe_stolen) {
@@ -9371,7 +9446,7 @@ index b663c2c..a93d6fe 100644
  
  #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
 diff --git a/kernel/sched/core.c b/kernel/sched/core.c
-index 817bf70..1494108 100644
+index 817bf70..a0f7815 100644
 --- a/kernel/sched/core.c
 +++ b/kernel/sched/core.c
 @@ -1501,7 +1501,9 @@ void scheduler_ipi(void)
@@ -9542,7 +9617,7 @@ index 817bf70..1494108 100644
  
        /*
         * The idle tasks have their own, simple scheduling class:
-@@ -8352,3 +8381,38 @@ struct cgroup_subsys cpuacct_subsys = {
+@@ -8352,3 +8381,40 @@ struct cgroup_subsys cpuacct_subsys = {
        .subsys_id = cpuacct_subsys_id,
  };
  #endif        /* CONFIG_CGROUP_CPUACCT */
@@ -9555,6 +9630,8 @@ index 817bf70..1494108 100644
 +
 +      preempt_disable();
 +
++      IPIPE_WARN_ONCE(__this_cpu_read(ipipe_percpu.task_hijacked) != NULL);
++
 +      __this_cpu_write(ipipe_percpu.task_hijacked, p);
 +      set_current_state(TASK_INTERRUPTIBLE | TASK_HARDENING);
 +      sched_submit_work(p);
diff --git a/ksrc/arch/blackfin/patches/ipipe-core-3.5.3-blackfin-2.patch 
b/ksrc/arch/blackfin/patches/ipipe-core-3.5.7-blackfin-3.patch
similarity index 97%
rename from ksrc/arch/blackfin/patches/ipipe-core-3.5.3-blackfin-2.patch
rename to ksrc/arch/blackfin/patches/ipipe-core-3.5.7-blackfin-3.patch
index 6e2d0c6..61908e1 100644
--- a/ksrc/arch/blackfin/patches/ipipe-core-3.5.3-blackfin-2.patch
+++ b/ksrc/arch/blackfin/patches/ipipe-core-3.5.7-blackfin-3.patch
@@ -12,7 +12,7 @@ index fef96f4..65a7acd 100644
  
  comment "Processor and Board Settings"
 diff --git a/arch/blackfin/include/asm/ipipe.h 
b/arch/blackfin/include/asm/ipipe.h
-index 17b5e92..50d41b9 100644
+index 17b5e92..60375ca 100644
 --- a/arch/blackfin/include/asm/ipipe.h
 +++ b/arch/blackfin/include/asm/ipipe.h
 @@ -28,7 +28,7 @@
@@ -32,7 +32,7 @@ index 17b5e92..50d41b9 100644
 -#define IPIPE_MAJOR_NUMBER    1
 -#define IPIPE_MINOR_NUMBER    16
 -#define IPIPE_PATCH_NUMBER    1
-+#define IPIPE_CORE_RELEASE    2
++#define IPIPE_CORE_RELEASE    3
  
  #ifdef CONFIG_SMP
  #error "I-pipe/blackfin: SMP not implemented"
@@ -1507,17 +1507,45 @@ index 78a666d..20e9852 100644
          CPU idle is a generic framework for supporting software-controlled
          idle processor power management.  It includes modular cross-platform
 diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
-index 6e1958a..2bb5d94 100644
+index 6e1958a..88bc148 100644
 --- a/drivers/tty/serial/8250/8250.c
 +++ b/drivers/tty/serial/8250/8250.c
-@@ -3055,6 +3055,56 @@ static int serial8250_resume(struct platform_device 
*dev)
+@@ -3055,6 +3055,84 @@ static int serial8250_resume(struct platform_device 
*dev)
        return 0;
  }
  
 +#if defined(CONFIG_IPIPE_DEBUG) && defined(CONFIG_SERIAL_8250_CONSOLE)
 +
++static IPIPE_DEFINE_SPINLOCK(ipipe_8250_lock);
++
 +#include <stdarg.h>
 +
++static void wait_for_xmitr_nodelay(struct uart_8250_port *up, int bits)
++{
++      unsigned int status, tmout = 10000;
++
++      for (;;) {
++              status = serial_in(up, UART_LSR);
++
++              up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
++
++              if ((status & bits) == bits)
++                      break;
++              if (--tmout == 0)
++                      break;
++              cpu_relax();
++      }
++}
++
++static void serial8250_console_putchar_nodelay(struct uart_port *port, int ch)
++{
++      struct uart_8250_port *up =
++              container_of(port, struct uart_8250_port, port);
++
++      wait_for_xmitr_nodelay(up, UART_LSR_THRE);
++      serial_port_out(port, UART_TX, ch);
++}
++
 +void __weak __ipipe_serial_debug(const char *fmt, ...)
 +{
 +        struct uart_8250_port *up = &serial8250_ports[0];
@@ -1538,7 +1566,7 @@ index 6e1958a..2bb5d94 100644
 +
 +        touch_nmi_watchdog();
 +
-+        flags = hard_local_irq_save();
++        spin_lock_irqsave(&ipipe_8250_lock, flags);
 +
 +        /*
 +         *      First save the IER then disable the interrupts
@@ -1550,16 +1578,16 @@ index 6e1958a..2bb5d94 100644
 +        else
 +                serial_out(up, UART_IER, 0);
 +
-+        uart_console_write(&up->port, buf, count, serial8250_console_putchar);
++        uart_console_write(&up->port, buf, count, 
serial8250_console_putchar_nodelay);
 +
 +        /*
 +         *      Finally, wait for transmitter to become empty
 +         *      and restore the IER
 +         */
-+        wait_for_xmitr(up, BOTH_EMPTY);
++        wait_for_xmitr_nodelay(up, BOTH_EMPTY);
 +        serial_out(up, UART_IER, ier);
 +
-+        hard_local_irq_restore(flags);
++        spin_unlock_irqrestore(&ipipe_8250_lock, flags);
 +}
 +
 +#endif
@@ -1714,6 +1742,20 @@ index 2533fdd..6559e2d 100644
        return prev;
  }
  
+diff --git a/include/asm-generic/mman-common.h 
b/include/asm-generic/mman-common.h
+index d030d2c..5612229 100644
+--- a/include/asm-generic/mman-common.h
++++ b/include/asm-generic/mman-common.h
+@@ -19,6 +19,9 @@
+ #define MAP_TYPE      0x0f            /* Mask for type of mapping */
+ #define MAP_FIXED     0x10            /* Interpret addr exactly */
+ #define MAP_ANONYMOUS 0x20            /* don't use a file */
++#ifndef MAP_BRK
++# define MAP_BRK      0
++#endif
+ #ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED
+ # define MAP_UNINITIALIZED 0x4000000  /* For anonymous mmap, memory could be 
uninitialized */
+ #else
 diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
 index d17784e..d8e2912 100644
 --- a/include/asm-generic/percpu.h
@@ -1883,10 +1925,10 @@ index e6bb36a..898a91a 100644
  
 diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
 new file mode 100644
-index 0000000..fca32ac
+index 0000000..a04ec49
 --- /dev/null
 +++ b/include/linux/ipipe.h
-@@ -0,0 +1,411 @@
+@@ -0,0 +1,431 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe.h
 + *
@@ -1957,6 +1999,7 @@ index 0000000..fca32ac
 +void __ipipe_reenter_root(void);
 +
 +int __ipipe_disable_ondemand_mappings(struct task_struct *p);
++
 +int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma);
 +
 +#ifdef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
@@ -2202,31 +2245,50 @@ index 0000000..fca32ac
 +
 +static inline void ipipe_enable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
 +
-+      if (WARN_ON_ONCE(chip->irq_unmask == NULL))
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
 +              return;
 +
-+      chip->irq_unmask(&desc->irq_data);
++      chip = irq_desc_get_chip(desc);
++
++      if (WARN_ON_ONCE(chip->irq_enable == NULL && chip->irq_unmask == NULL))
++              return;
++
++      if (chip->irq_enable)
++              chip->irq_enable(&desc->irq_data);
++      else
++              chip->irq_unmask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_disable_irq(unsigned int irq)
 +{
-+      struct irq_desc *desc = irq_to_desc(irq);
-+      struct irq_chip *chip = irq_desc_get_chip(desc);
++      struct irq_desc *desc;
++      struct irq_chip *chip;
++
++      desc = irq_to_desc(irq);
++      if (desc == NULL)
++              return;
++
++      chip = irq_desc_get_chip(desc);
 +
-+      if (WARN_ON_ONCE(chip->irq_mask == NULL))
++      if (WARN_ON_ONCE(chip->irq_disable == NULL && chip->irq_mask == NULL))
 +              return;
 +
-+      chip->irq_mask(&desc->irq_data);
++      if (chip->irq_disable)
++              chip->irq_disable(&desc->irq_data);
++      else
++              chip->irq_mask(&desc->irq_data);
 +}
 +
 +static inline void ipipe_end_irq(unsigned int irq)
 +{
 +      struct irq_desc *desc = irq_to_desc(irq);
 +
-+      desc->ipipe_end(irq, desc);
++      if (desc)
++              desc->ipipe_end(irq, desc);
 +}
 +
 +static inline int ipipe_chained_irq_p(struct irq_desc *desc)
@@ -4122,7 +4184,7 @@ index 9c9f049..62c894150 100644
  static inline void __raw_read_lock(rwlock_t *lock)
  {
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 4a1f493..eb74259 100644
+index e63650f..beb101e 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -62,6 +62,7 @@ struct sched_param {
@@ -4178,7 +4240,7 @@ index 4a1f493..eb74259 100644
  
  #define MMF_INIT_MASK         (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
  
-@@ -1516,6 +1537,10 @@ struct task_struct {
+@@ -1519,6 +1540,10 @@ struct task_struct {
        short pref_node_fork;
  #endif
        struct rcu_head rcu;
@@ -4189,7 +4251,7 @@ index 4a1f493..eb74259 100644
  
        /*
         * cache last used pipe for splice
-@@ -1798,6 +1823,10 @@ extern void thread_group_times(struct task_struct *p, 
cputime_t *ut, cputime_t *
+@@ -1801,6 +1826,10 @@ extern void thread_group_times(struct task_struct *p, 
cputime_t *ut, cputime_t *
  #define PF_MUTEX_TESTER       0x20000000      /* Thread belongs to the rt 
mutex tester */
  #define PF_FREEZER_SKIP       0x40000000      /* Freezer should not count it 
as freezable */
  
@@ -4464,10 +4526,10 @@ index a26e2fb..71348f2 100644
  
  #define arch_read_can_lock(lock)      (((void)(lock), 1))
 diff --git a/include/linux/time.h b/include/linux/time.h
-index c81c5e4..e82782a 100644
+index b51e664..c7d91b9 100644
 --- a/include/linux/time.h
 +++ b/include/linux/time.h
-@@ -126,6 +126,7 @@ struct timespec get_monotonic_coarse(void);
+@@ -151,6 +151,7 @@ struct timespec get_monotonic_coarse(void);
  void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
                                struct timespec *wtom, struct timespec *sleep);
  void timekeeping_inject_sleeptime(struct timespec *delta);
@@ -4553,7 +4615,7 @@ index 46ce8da..492e0e7 100644
        exit_shm(tsk);
        exit_files(tsk);
 diff --git a/kernel/fork.c b/kernel/fork.c
-index f00e319..fe4e0be 100644
+index f9d0499..234af7f 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
 @@ -315,6 +315,7 @@ static struct task_struct *dup_task_struct(struct 
task_struct *orig)
@@ -4653,7 +4715,7 @@ index 0000000..ce56a9c
 +       def_bool y if IPIPE_LEGACY
 diff --git a/kernel/ipipe/Kconfig.debug b/kernel/ipipe/Kconfig.debug
 new file mode 100644
-index 0000000..ba87335
+index 0000000..40c82a2
 --- /dev/null
 +++ b/kernel/ipipe/Kconfig.debug
 @@ -0,0 +1,95 @@
@@ -4683,8 +4745,8 @@ index 0000000..ba87335
 +config IPIPE_TRACE
 +      bool "Latency tracing"
 +      depends on IPIPE_DEBUG
-+      select ARCH_WANT_FRAME_POINTERS
-+      select FRAME_POINTER
++      select ARCH_WANT_FRAME_POINTERS if !ARM_UNWIND
++      select FRAME_POINTER if !ARM_UNWIND
 +      select KALLSYMS
 +      select PROC_FS
 +      ---help---
@@ -5037,10 +5099,10 @@ index 0000000..1147bf4
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..b0af234
+index 0000000..3bc6ef5
 --- /dev/null
 +++ b/kernel/ipipe/core.c
-@@ -0,0 +1,1705 @@
+@@ -0,0 +1,1733 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/core.c
 + *
@@ -5891,7 +5953,9 @@ index 0000000..b0af234
 +      unsigned long flags;
 +      int ret = 0;
 +
++#ifndef CONFIG_IPIPE_LEGACY
 +      ipipe_root_only();
++#endif /* CONFIG_IPIPE_LEGACY */
 +
 +      if (handler == NULL ||
 +          (irq >= IPIPE_NR_XIRQS && !ipipe_virtual_irq_p(irq)))
@@ -5926,7 +5990,9 @@ index 0000000..b0af234
 +{
 +      unsigned long flags;
 +
++#ifndef CONFIG_IPIPE_LEGACY
 +      ipipe_root_only();
++#endif /* CONFIG_IPIPE_LEGACY */
 +
 +      spin_lock_irqsave(&__ipipe_lock, flags);
 +
@@ -6105,25 +6171,50 @@ index 0000000..b0af234
 +{
 +}
 +
++#ifdef CONFIG_IPIPE_LEGACY
++
++static inline void complete_domain_migration(void) /* hw IRQs off */
++{
++      current->state &= ~TASK_HARDENING;
++}
++
++#else /* !CONFIG_IPIPE_LEGACY */
++
 +static void complete_domain_migration(void) /* hw IRQs off */
 +{
++      struct ipipe_percpu_domain_data *p;
 +      struct ipipe_percpu_data *pd;
-+      struct task_struct *p;
++      struct task_struct *t;
 +
++      ipipe_root_only();
 +      pd = __this_cpu_ptr(&ipipe_percpu);
-+      p = pd->task_hijacked;
-+      if (p) {
-+              p->state &= ~TASK_HARDENING;
-+              pd->task_hijacked = NULL;
-+              ipipe_migration_hook(p);
-+      }
++      t = pd->task_hijacked;
++      if (t == NULL)
++              return;
++
++      pd->task_hijacked = NULL;
++      t->state &= ~TASK_HARDENING;
++      if (t->state != TASK_INTERRUPTIBLE)
++              /* Migration aborted (by signal). */
++              return;
++
++      p = ipipe_this_cpu_head_context();
++      IPIPE_WARN_ONCE(test_bit(IPIPE_STALL_FLAG, &p->status));
++      /*
++       * hw IRQs are disabled, but the completion hook assumes the
++       * head domain is logically stalled: fix it up.
++       */
++      __set_bit(IPIPE_STALL_FLAG, &p->status);
++      ipipe_migration_hook(t);
++      __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +}
 +
++#endif /* !CONFIG_IPIPE_LEGACY */
++
 +void __ipipe_complete_domain_migration(void)
 +{
 +      unsigned long flags;
 +
-+      ipipe_root_only();
 +      flags = hard_local_irq_save();
 +      complete_domain_migration();
 +      hard_local_irq_restore(flags);
@@ -6138,12 +6229,10 @@ index 0000000..b0af234
 +      hard_local_irq_disable();
 +#endif
 +      x = __ipipe_root_p;
-+
-+#ifdef CONFIG_IPIPE_LEGACY
-+      current->state &= ~TASK_HARDENING;
-+#else
-+      complete_domain_migration();
-+#endif        /* !CONFIG_IPIPE_LEGACY */
++#ifndef CONFIG_IPIPE_LEGACY
++      if (x)
++#endif
++              complete_domain_migration();
 +
 +#ifndef CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH
 +      if (x)
@@ -6187,18 +6276,19 @@ index 0000000..b0af234
 +      head->irqs[irq].handler(irq, head->irqs[irq].cookie);
 +      __ipipe_run_irqtail(irq);
 +      hard_local_irq_disable();
++      p = ipipe_this_cpu_head_context();
 +      __clear_bit(IPIPE_STALL_FLAG, &p->status);
 +
 +      /* Are we still running in the head domain? */
 +      if (likely(__ipipe_current_context == p)) {
 +              /* Did we enter this code over the head domain? */
-+              if (old == p) {
++              if (old->domain == head) {
 +                      /* Yes, do immediate synchronization. */
 +                      if (__ipipe_ipending_p(p))
 +                              __ipipe_sync_stage();
 +                      return;
 +              }
-+              __ipipe_set_current_context(old);
++              __ipipe_set_current_context(ipipe_this_cpu_root_context());
 +      }
 +
 +      /*
@@ -6748,10 +6838,10 @@ index 0000000..b0af234
 +EXPORT_SYMBOL_GPL(__ipipe_post_work_root);
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..9a076ab
+index 0000000..4281cb1
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,480 @@
+@@ -0,0 +1,483 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -7084,6 +7174,7 @@ index 0000000..9a076ab
 +{
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +      unsigned long flags;
 +      int steal, ret;
 +
@@ -7123,10 +7214,10 @@ index 0000000..9a076ab
 +  done:
 +      ipipe_critical_exit(flags);
 +
-+#ifdef CONFIG_GENERIC_CLOCKEVENTS
-+      if (evtdev && evtdev->mode == CLOCK_EVT_MODE_UNUSED)
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
 +              ipipe_enable_irq(timer->irq);
-+#endif
++
 +      return ret;
 +}
 +
@@ -7135,15 +7226,17 @@ index 0000000..9a076ab
 +      unsigned long __maybe_unused flags;
 +      struct clock_event_device *evtdev;
 +      struct ipipe_timer *timer;
++      struct irq_desc *desc;
 +
 +      timer = per_cpu(percpu_timer, cpu);
 +      evtdev = timer->host_timer;
 +
++      desc = irq_to_desc(timer->irq);
++      if (desc && irqd_irq_disabled(&desc->irq_data))
++              ipipe_disable_irq(timer->irq);
++
 +#ifdef CONFIG_GENERIC_CLOCKEVENTS
 +      if (evtdev) {
-+              if (evtdev->mode == CLOCK_EVT_MODE_UNUSED)
-+                      ipipe_disable_irq(timer->irq);
-+
 +              flags = ipipe_critical_enter(NULL);
 +
 +              if (evtdev->ipipe_stolen) {
@@ -8681,7 +8774,7 @@ index 0000000..1d9997a
 +#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
 +}
 diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
-index eebd6d5..60f9f14 100644
+index eebd6d5..c5433eb 100644
 --- a/kernel/irq/chip.c
 +++ b/kernel/irq/chip.c
 @@ -15,6 +15,7 @@
@@ -8814,7 +8907,7 @@ index eebd6d5..60f9f14 100644
  }
  
  /**
-@@ -615,17 +646,133 @@ void handle_percpu_devid_irq(unsigned int irq, struct 
irq_desc *desc)
+@@ -615,17 +646,134 @@ void handle_percpu_devid_irq(unsigned int irq, struct 
irq_desc *desc)
  
        kstat_incr_irqs_this_cpu(irq, desc);
  
@@ -8944,11 +9037,12 @@ index eebd6d5..60f9f14 100644
 +}
 +
 +#endif /* !CONFIG_IPIPE */
++EXPORT_SYMBOL_GPL(__fixup_irq_handler);
 +
  void
  __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
                  const char *name)
-@@ -643,6 +790,8 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t 
handle, int is_chained,
+@@ -643,6 +791,8 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t 
handle, int is_chained,
                        goto out;
        }
  
@@ -9331,7 +9425,7 @@ index 146827f..8927a03 100644
  
  #ifdef CONFIG_A11Y_BRAILLE_CONSOLE
 diff --git a/kernel/sched/core.c b/kernel/sched/core.c
-index 468bdd4..ec38567 100644
+index 9f81a3a..f8c95cf 100644
 --- a/kernel/sched/core.c
 +++ b/kernel/sched/core.c
 @@ -1499,7 +1499,9 @@ void scheduler_ipi(void)
@@ -9401,7 +9495,7 @@ index 468bdd4..ec38567 100644
  }
  
  /*
-@@ -3242,6 +3255,7 @@ notrace unsigned long get_parent_ip(unsigned long addr)
+@@ -3248,6 +3261,7 @@ notrace unsigned long get_parent_ip(unsigned long addr)
  
  void __kprobes add_preempt_count(int val)
  {
@@ -9409,7 +9503,7 @@ index 468bdd4..ec38567 100644
  #ifdef CONFIG_DEBUG_PREEMPT
        /*
         * Underflow?
-@@ -3310,6 +3324,7 @@ static noinline void __schedule_bug(struct task_struct 
*prev)
+@@ -3316,6 +3330,7 @@ static noinline void __schedule_bug(struct task_struct 
*prev)
   */
  static inline void schedule_debug(struct task_struct *prev)
  {
@@ -9417,7 +9511,7 @@ index 468bdd4..ec38567 100644
        /*
         * Test if we are atomic. Since do_exit() needs to call into
         * schedule() atomically, we ignore that path for now.
-@@ -3362,7 +3377,7 @@ pick_next_task(struct rq *rq)
+@@ -3368,7 +3383,7 @@ pick_next_task(struct rq *rq)
  /*
   * __schedule() is the main scheduler function.
   */
@@ -9426,7 +9520,7 @@ index 468bdd4..ec38567 100644
  {
        struct task_struct *prev, *next;
        unsigned long *switch_count;
-@@ -3376,6 +3391,10 @@ need_resched:
+@@ -3382,6 +3397,10 @@ need_resched:
        rcu_note_context_switch(cpu);
        prev = rq->curr;
  
@@ -9437,7 +9531,7 @@ index 468bdd4..ec38567 100644
        schedule_debug(prev);
  
        if (sched_feat(HRTICK))
-@@ -3422,7 +3441,8 @@ need_resched:
+@@ -3428,7 +3447,8 @@ need_resched:
                rq->curr = next;
                ++*switch_count;
  
@@ -9447,7 +9541,7 @@ index 468bdd4..ec38567 100644
                /*
                 * The context switch have flipped the stack from under us
                 * and restored the local variables which were saved when
-@@ -3431,14 +3451,18 @@ need_resched:
+@@ -3437,14 +3457,18 @@ need_resched:
                 */
                cpu = smp_processor_id();
                rq = cpu_rq(cpu);
@@ -9467,7 +9561,7 @@ index 468bdd4..ec38567 100644
  }
  
  static inline void sched_submit_work(struct task_struct *tsk)
-@@ -3538,7 +3562,8 @@ asmlinkage void __sched notrace preempt_schedule(void)
+@@ -3544,7 +3568,8 @@ asmlinkage void __sched notrace preempt_schedule(void)
  
        do {
                add_preempt_count_notrace(PREEMPT_ACTIVE);
@@ -9477,7 +9571,7 @@ index 468bdd4..ec38567 100644
                sub_preempt_count_notrace(PREEMPT_ACTIVE);
  
                /*
-@@ -3601,6 +3626,8 @@ static void __wake_up_common(wait_queue_head_t *q, 
unsigned int mode,
+@@ -3607,6 +3632,8 @@ static void __wake_up_common(wait_queue_head_t *q, 
unsigned int mode,
  {
        wait_queue_t *curr, *next;
  
@@ -9486,7 +9580,7 @@ index 468bdd4..ec38567 100644
        list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
                unsigned flags = curr->flags;
  
-@@ -4379,6 +4406,7 @@ recheck:
+@@ -4385,6 +4412,7 @@ recheck:
        oldprio = p->prio;
        prev_class = p->sched_class;
        __setscheduler(rq, p, policy, param->sched_priority);
@@ -9494,7 +9588,7 @@ index 468bdd4..ec38567 100644
  
        if (running)
                p->sched_class->set_curr_task(rq);
-@@ -5126,6 +5154,7 @@ void __cpuinit init_idle(struct task_struct *idle, int 
cpu)
+@@ -5132,6 +5160,7 @@ void __cpuinit init_idle(struct task_struct *idle, int 
cpu)
  
        /* Set the preempt count _outside_ the spinlocks! */
        task_thread_info(idle)->preempt_count = 0;
@@ -9502,7 +9596,7 @@ index 468bdd4..ec38567 100644
  
        /*
         * The idle tasks have their own, simple scheduling class:
-@@ -8513,3 +8542,38 @@ struct cgroup_subsys cpuacct_subsys = {
+@@ -8559,3 +8588,40 @@ struct cgroup_subsys cpuacct_subsys = {
        .base_cftypes = files,
  };
  #endif        /* CONFIG_CGROUP_CPUACCT */
@@ -9515,6 +9609,8 @@ index 468bdd4..ec38567 100644
 +
 +      preempt_disable();
 +
++      IPIPE_WARN_ONCE(__this_cpu_read(ipipe_percpu.task_hijacked) != NULL);
++
 +      __this_cpu_write(ipipe_percpu.task_hijacked, p);
 +      set_current_state(TASK_INTERRUPTIBLE | TASK_HARDENING);
 +      sched_submit_work(p);
@@ -9722,10 +9818,10 @@ index da6c9ec..0c4be00 100644
  }
  
 diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
-index 4a08472..cc88827 100644
+index a057ed4..32138a1 100644
 --- a/kernel/time/tick-sched.c
 +++ b/kernel/time/tick-sched.c
-@@ -656,7 +656,7 @@ static void tick_nohz_handler(struct clock_event_device 
*dev)
+@@ -657,7 +657,7 @@ static void tick_nohz_handler(struct clock_event_device 
*dev)
                ts->idle_jiffies++;
        }
  
@@ -9734,7 +9830,7 @@ index 4a08472..cc88827 100644
        profile_tick(CPU_PROFILING);
  
        while (tick_nohz_reprogram(ts, now)) {
-@@ -813,7 +813,7 @@ static enum hrtimer_restart tick_sched_timer(struct 
hrtimer *timer)
+@@ -814,7 +814,7 @@ static enum hrtimer_restart tick_sched_timer(struct 
hrtimer *timer)
                        touch_softlockup_watchdog();
                        ts->idle_jiffies++;
                }
@@ -9744,10 +9840,10 @@ index 4a08472..cc88827 100644
        }
  
 diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
-index 3447cfa..08b892d 100644
+index 63c88c1..4779fb3 100644
 --- a/kernel/time/timekeeping.c
 +++ b/kernel/time/timekeeping.c
-@@ -1336,3 +1336,9 @@ void xtime_update(unsigned long ticks)
+@@ -1362,3 +1362,9 @@ void xtime_update(unsigned long ticks)
        do_timer(ticks);
        write_sequnlock(&xtime_lock);
  }
@@ -9927,8 +10023,20 @@ index 4c0d0e5..886125d 100644
                goto out;
  
        /*
+diff --git a/mm/Kconfig b/mm/Kconfig
+index 82fed4e..0ebccef 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -314,6 +314,7 @@ config NOMMU_INITIAL_TRIM_EXCESS
+ config TRANSPARENT_HUGEPAGE
+       bool "Transparent Hugepage Support"
+       depends on X86 && MMU
++      depends on !IPIPE
+       select COMPACTION
+       help
+         Transparent Hugepages allows the kernel to use huge pages and
 diff --git a/mm/memory.c b/mm/memory.c
-index 2466d12..ab93d65 100644
+index 2466d12..4230192 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
 @@ -822,6 +822,32 @@ out:
@@ -10005,7 +10113,7 @@ index 2466d12..ab93d65 100644
 +      struct page *uncow_page = NULL;
 +#ifdef CONFIG_IPIPE
 +      int do_cow_break = 0;
-+again:
+ again:
 +      if (do_cow_break) {
 +              uncow_page = alloc_page_vma(GFP_HIGHUSER, vma, addr);
 +              if (uncow_page == NULL)
@@ -10013,7 +10121,7 @@ index 2466d12..ab93d65 100644
 +              do_cow_break = 0;
 +      }
 +#else
- again:
++again:
 +#endif
        init_rss_vec(rss);
  
@@ -10087,92 +10195,13 @@ index 2466d12..ab93d65 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
-@@ -4026,3 +4072,117 @@ void copy_user_huge_page(struct page *dst, struct page 
*src,
+@@ -4026,3 +4072,38 @@ void copy_user_huge_page(struct page *dst, struct page 
*src,
        }
  }
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
 +
 +#ifdef CONFIG_IPIPE
 +
-+static inline int ipipe_pin_pte_range(struct mm_struct *mm, pmd_t *pmd,
-+                                    struct vm_area_struct *vma,
-+                                    unsigned long addr, unsigned long end)
-+{
-+      spinlock_t *ptl;
-+      pte_t *pte;
-+
-+      do {
-+              pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
-+              if (!pte)
-+                      continue;
-+
-+              if (!pte_present(*pte) || pte_write(*pte)) {
-+                      pte_unmap_unlock(pte, ptl);
-+                      continue;
-+              }
-+
-+              if (do_wp_page(mm, vma, addr, pte, pmd, ptl, *pte) == 
VM_FAULT_OOM)
-+                      return -ENOMEM;
-+      } while (addr += PAGE_SIZE, addr != end);
-+      return 0;
-+}
-+
-+static inline int ipipe_pin_pmd_range(struct mm_struct *mm, pud_t *pud,
-+                                    struct vm_area_struct *vma,
-+                                    unsigned long addr, unsigned long end)
-+{
-+      unsigned long next;
-+      pmd_t *pmd;
-+
-+      pmd = pmd_offset(pud, addr);
-+      do {
-+              next = pmd_addr_end(addr, end);
-+              if (pmd_none_or_clear_bad(pmd))
-+                      continue;
-+              if (ipipe_pin_pte_range(mm, pmd, vma, addr, next))
-+                      return -ENOMEM;
-+      } while (pmd++, addr = next, addr != end);
-+      return 0;
-+}
-+
-+static inline int ipipe_pin_pud_range(struct mm_struct *mm, pgd_t *pgd,
-+                                    struct vm_area_struct *vma,
-+                                    unsigned long addr, unsigned long end)
-+{
-+      unsigned long next;
-+      pud_t *pud;
-+
-+      pud = pud_offset(pgd, addr);
-+      do {
-+              next = pud_addr_end(addr, end);
-+              if (pud_none_or_clear_bad(pud))
-+                      continue;
-+              if (ipipe_pin_pmd_range(mm, pud, vma, addr, next))
-+                      return -ENOMEM;
-+      } while (pud++, addr = next, addr != end);
-+      return 0;
-+}
-+
-+int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma)
-+{
-+      unsigned long addr, next, end;
-+      pgd_t *pgd;
-+
-+      addr = vma->vm_start;
-+      end = vma->vm_end;
-+
-+      pgd = pgd_offset(mm, addr);
-+      do {
-+              next = pgd_addr_end(addr, end);
-+              if (pgd_none_or_clear_bad(pgd))
-+                      continue;
-+              if (ipipe_pin_pud_range(mm, pgd, vma, addr, next))
-+                      return -ENOMEM;
-+      } while (pgd++, addr = next, addr != end);
-+
-+      return 0;
-+}
-+
 +int __ipipe_disable_ondemand_mappings(struct task_struct *tsk)
 +{
 +      struct vm_area_struct *vma;
@@ -10205,6 +10234,45 @@ index 2466d12..ab93d65 100644
 +EXPORT_SYMBOL_GPL(__ipipe_disable_ondemand_mappings);
 +
 +#endif
+diff --git a/mm/mlock.c b/mm/mlock.c
+index ef726e8..158828b 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -624,3 +624,21 @@ void user_shm_unlock(size_t size, struct user_struct 
*user)
+       spin_unlock(&shmlock_user_lock);
+       free_uid(user);
+ }
++
++#ifdef CONFIG_IPIPE
++int __ipipe_pin_vma(struct mm_struct *mm, struct vm_area_struct *vma)
++{
++      int ret;
++
++      if (vma->vm_flags & (VM_IO | VM_PFNMAP))
++              return 0;
++
++      if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
++          is_vm_hugetlb_page(vma) || vma == get_gate_vma(mm))) {
++              ret = __mlock_vma_pages_range(vma, vma->vm_start, vma->vm_end,
++                                            NULL);
++              return (ret < 0) ? ret : 0;
++      } else
++              return make_pages_present(vma->vm_start, vma->vm_end);
++}
++#endif
+diff --git a/mm/mmap.c b/mm/mmap.c
+index fa1f274..a715aeb 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2174,7 +2174,7 @@ static unsigned long do_brk(unsigned long addr, unsigned 
long len)
+ 
+       flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
+ 
+-      error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED);
++      error = get_unmapped_area(NULL, addr, len, 0, MAP_FIXED | MAP_BRK);
+       if (error & ~PAGE_MASK)
+               return error;
+ 
 diff --git a/mm/mmu_context.c b/mm/mmu_context.c
 index 3dcfaf4..e4ac923 100644
 --- a/mm/mmu_context.c
@@ -10230,61 +10298,22 @@ index 3dcfaf4..e4ac923 100644
  
        if (active_mm != mm)
 diff --git a/mm/mprotect.c b/mm/mprotect.c
-index a409926..195b91e 100644
+index a409926..057b1d8 100644
 --- a/mm/mprotect.c
 +++ b/mm/mprotect.c
-@@ -147,6 +147,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct 
vm_area_struct **pprev,
- {
-       struct mm_struct *mm = vma->vm_mm;
-       unsigned long oldflags = vma->vm_flags;
-+      unsigned long protflags;
-       long nrpages = (end - start) >> PAGE_SHIFT;
-       unsigned long charged = 0;
-       pgoff_t pgoff;
-@@ -205,8 +206,17 @@ success:
-        * held in write mode.
-        */
-       vma->vm_flags = newflags;
-+      protflags = newflags;
-+#ifdef CONFIG_IPIPE
-+      /*
-+       * Enforce non-COW vm_page_prot by faking VM_SHARED on locked regions.
-+       */
-+      if (test_bit(MMF_VM_PINNED, &mm->flags) &&
-+          ((vma->vm_flags | mm->def_flags) & VM_LOCKED))
-+              protflags |= VM_SHARED;
-+#endif
-       vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
--                                        vm_get_page_prot(newflags));
-+                                        vm_get_page_prot(protflags));
- 
-       if (vma_wants_writenotify(vma)) {
-               vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
-@@ -214,6 +224,24 @@ success:
-       }
- 
-       mmu_notifier_invalidate_range_start(mm, start, end);
+@@ -218,6 +218,12 @@ success:
+               hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
+       else
+               change_protection(vma, start, end, vma->vm_page_prot, 
dirty_accountable);
 +#ifdef CONFIG_IPIPE
-+      /*
-+       * Privatize potential COW pages
-+       */
 +      if (test_bit(MMF_VM_PINNED, &mm->flags) &&
-+          (((vma->vm_flags | mm->def_flags) & (VM_LOCKED | VM_WRITE)) ==
-+           (VM_LOCKED | VM_WRITE))) {
-+              error = __ipipe_pin_vma(mm, vma);
-+              if (error)
-+                      /*
-+                       * OOM. Just revert the fake VM_SHARED so that the
-+                       * zero page cannot be overwritten.
-+                       */
-+                      vma->vm_page_prot =
-+                              pgprot_modify(vma->vm_page_prot,
-+                                            vm_get_page_prot(newflags));
-+      }
++          ((vma->vm_flags | mm->def_flags) & VM_LOCKED) &&
++          (vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
++              __ipipe_pin_vma(mm, vma);
 +#endif
-       if (is_vm_hugetlb_page(vma))
-               hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
-       else
+       mmu_notifier_invalidate_range_end(mm, start, end);
+       vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
+       vm_stat_account(mm, newflags, vma->vm_file, nrpages);
 diff --git a/mm/vmalloc.c b/mm/vmalloc.c
 index 2aad499..52aaaf7 100644
 --- a/mm/vmalloc.c


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

Reply via email to