Module: xenomai-2.6 Branch: master Commit: 5c17a0a5c9ddd6110fb334bb3a330bf2b8420133 URL: http://git.xenomai.org/?p=xenomai-2.6.git;a=commit;h=5c17a0a5c9ddd6110fb334bb3a330bf2b8420133
Author: Philippe Gerum <r...@xenomai.org> Date: Tue Jan 22 12:04:23 2013 +0100 powerpc: upgrade I-pipe support --- ...c-2.patch => ipipe-core-3.2.21-powerpc-4.patch} | 127 ++++-- ...pc-2.patch => ipipe-core-3.4.6-powerpc-4.patch} | 187 ++++++-- ...pc-2.patch => ipipe-core-3.5.7-powerpc-3.patch} | 507 +++++++++++--------- 3 files changed, 502 insertions(+), 319 deletions(-) diff --git a/ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-2.patch b/ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-4.patch similarity index 99% rename from ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-2.patch rename to ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-4.patch index 3ac7a2d..48c3f73 100644 --- a/ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-2.patch +++ b/ksrc/arch/powerpc/patches/ipipe-core-3.2.21-powerpc-4.patch @@ -285,7 +285,7 @@ index bb712c9..8885e9b 100644 * or should we not care like we do now ? --BenH. diff --git a/arch/powerpc/include/asm/ipipe.h b/arch/powerpc/include/asm/ipipe.h new file mode 100644 -index 0000000..62ac2ce +index 0000000..c935bf8 --- /dev/null +++ b/arch/powerpc/include/asm/ipipe.h @@ -0,0 +1,187 @@ @@ -337,7 +337,7 @@ index 0000000..62ac2ce +#include <asm/paca.h> +#endif + -+#define IPIPE_CORE_RELEASE 2 ++#define IPIPE_CORE_RELEASE 4 + +struct ipipe_domain; + @@ -889,7 +889,7 @@ index b0b06d8..cef2379 100644 #ifdef CONFIG_IRQSOFF_TRACER /* diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h -index a73668a..e51b0e2 100644 +index a73668a..5eda09f 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -36,15 +36,112 @@ extern void switch_cop(struct mm_struct *next); @@ -1048,15 +1048,23 @@ index a73668a..e51b0e2 100644 } #define deactivate_mm(tsk,mm) do { } while (0) -@@ -99,7 +209,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +@@ -96,11 +206,15 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + */ + static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) + { ++#ifndef CONFIG_IPIPE unsigned long flags; local_irq_save(flags); - switch_mm(prev, next, current); ++#endif + __switch_mm(prev, next, current); ++#ifndef CONFIG_IPIPE local_irq_restore(flags); ++#endif } + /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index e6fae49..7a5f3ce 100644 --- a/arch/powerpc/include/asm/mpic.h @@ -5696,10 +5704,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 + * @@ -5770,6 +5778,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 @@ -6002,31 +6011,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; ++ ++ desc = irq_to_desc(irq); ++ if (desc == NULL) ++ return; ++ ++ chip = irq_desc_get_chip(desc); + -+ if (WARN_ON_ONCE(chip->irq_unmask == NULL)) ++ if (WARN_ON_ONCE(chip->irq_enable == NULL && chip->irq_unmask == NULL)) + return; + -+ chip->irq_unmask(&desc->irq_data); ++ 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) @@ -8757,10 +8785,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 + * @@ -9825,25 +9853,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); @@ -9858,12 +9911,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) @@ -10469,10 +10520,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 + * @@ -10734,6 +10785,7 @@ index 0000000..a2b8672 +{ + struct clock_event_device *evtdev; + struct ipipe_timer *timer; ++ struct irq_desc *desc; + unsigned long flags; + int steal, rc; + @@ -10774,6 +10826,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; +} + @@ -10781,11 +10837,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/powerpc/patches/ipipe-core-3.4.6-powerpc-2.patch b/ksrc/arch/powerpc/patches/ipipe-core-3.4.6-powerpc-4.patch similarity index 99% rename from ksrc/arch/powerpc/patches/ipipe-core-3.4.6-powerpc-2.patch rename to ksrc/arch/powerpc/patches/ipipe-core-3.4.6-powerpc-4.patch index cbded48..2fccba3 100644 --- a/ksrc/arch/powerpc/patches/ipipe-core-3.4.6-powerpc-2.patch +++ b/ksrc/arch/powerpc/patches/ipipe-core-3.4.6-powerpc-4.patch @@ -262,7 +262,7 @@ index 907e9fd..93f7996 100644 * or should we not care like we do now ? --BenH. diff --git a/arch/powerpc/include/asm/ipipe.h b/arch/powerpc/include/asm/ipipe.h new file mode 100644 -index 0000000..e4bb785 +index 0000000..d9b52b9 --- /dev/null +++ b/arch/powerpc/include/asm/ipipe.h @@ -0,0 +1,185 @@ @@ -307,7 +307,7 @@ index 0000000..e4bb785 +#include <linux/cache.h> +#include <linux/threads.h> + -+#define IPIPE_CORE_RELEASE 2 ++#define IPIPE_CORE_RELEASE 4 + +struct ipipe_domain; + @@ -851,7 +851,7 @@ index 0000000..2bc8217 + +#endif /* !_ASM_POWERPC_IPIPE_HWIRQ_H */ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h -index a73668a..a8019f2 100644 +index a73668a..c4254a3 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -36,15 +36,99 @@ extern void switch_cop(struct mm_struct *next); @@ -999,7 +999,7 @@ index a73668a..a8019f2 100644 + __do_switch_mm(prev, next, tsk); +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH */ +} -+ + +/* + * switch_mm is the entry point called from the architecture independent + * code in kernel/sched.c. @@ -1016,7 +1016,7 @@ index a73668a..a8019f2 100644 + hard_local_irq_restore(flags); +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH */ +} - ++ +/* + * ipipe_switch_mm_head is reserved to the head domain for switching + * mmu context. @@ -1030,15 +1030,23 @@ index a73668a..a8019f2 100644 } #define deactivate_mm(tsk,mm) do { } while (0) -@@ -99,7 +221,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +@@ -96,11 +218,15 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + */ + static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) + { ++#ifndef CONFIG_IPIPE unsigned long flags; local_irq_save(flags); - switch_mm(prev, next, current); ++#endif + __switch_mm(prev, next, current); ++#ifndef CONFIG_IPIPE local_irq_restore(flags); ++#endif } + /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index c9f698a..cd4f633 100644 --- a/arch/powerpc/include/asm/mpic.h @@ -4774,17 +4782,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]; @@ -4805,7 +4841,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 @@ -4817,16 +4853,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 @@ -5164,10 +5200,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 + * @@ -5238,6 +5274,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 @@ -5478,31 +5515,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; + -+ if (WARN_ON_ONCE(chip->irq_mask == NULL)) ++ desc = irq_to_desc(irq); ++ if (desc == NULL) + return; + -+ chip->irq_mask(&desc->irq_data); ++ chip = irq_desc_get_chip(desc); ++ ++ if (WARN_ON_ONCE(chip->irq_disable == NULL && chip->irq_mask == NULL)) ++ return; ++ ++ 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) @@ -8325,10 +8381,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 + * @@ -9393,25 +9449,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); @@ -9426,12 +9507,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) @@ -9475,18 +9554,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()); + } + + /* @@ -10037,10 +10117,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 + * @@ -10373,6 +10453,7 @@ index 0000000..9a076ab +{ + struct clock_event_device *evtdev; + struct ipipe_timer *timer; ++ struct irq_desc *desc; + unsigned long flags; + int steal, ret; + @@ -10412,10 +10493,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; +} + @@ -10424,15 +10505,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) { @@ -12629,7 +12712,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) @@ -12800,7 +12883,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 */ @@ -12813,6 +12896,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/powerpc/patches/ipipe-core-3.5.3-powerpc-2.patch b/ksrc/arch/powerpc/patches/ipipe-core-3.5.7-powerpc-3.patch similarity index 97% rename from ksrc/arch/powerpc/patches/ipipe-core-3.5.3-powerpc-2.patch rename to ksrc/arch/powerpc/patches/ipipe-core-3.5.7-powerpc-3.patch index 7a6ac8c..713ec3d 100644 --- a/ksrc/arch/powerpc/patches/ipipe-core-3.5.3-powerpc-2.patch +++ b/ksrc/arch/powerpc/patches/ipipe-core-3.5.7-powerpc-3.patch @@ -262,7 +262,7 @@ index 0554ab0..ec312e0 100644 * or should we not care like we do now ? --BenH. diff --git a/arch/powerpc/include/asm/ipipe.h b/arch/powerpc/include/asm/ipipe.h new file mode 100644 -index 0000000..e4bb785 +index 0000000..4182870 --- /dev/null +++ b/arch/powerpc/include/asm/ipipe.h @@ -0,0 +1,185 @@ @@ -307,7 +307,7 @@ index 0000000..e4bb785 +#include <linux/cache.h> +#include <linux/threads.h> + -+#define IPIPE_CORE_RELEASE 2 ++#define IPIPE_CORE_RELEASE 3 + +struct ipipe_domain; + @@ -851,7 +851,7 @@ index 0000000..2bc8217 + +#endif /* !_ASM_POWERPC_IPIPE_HWIRQ_H */ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h -index a73668a..a8019f2 100644 +index a73668a..c4254a3 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -36,15 +36,99 @@ extern void switch_cop(struct mm_struct *next); @@ -999,7 +999,7 @@ index a73668a..a8019f2 100644 + __do_switch_mm(prev, next, tsk); +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH */ +} -+ + +/* + * switch_mm is the entry point called from the architecture independent + * code in kernel/sched.c. @@ -1016,7 +1016,7 @@ index a73668a..a8019f2 100644 + hard_local_irq_restore(flags); +#endif /* !CONFIG_IPIPE_WANT_PREEMPTIBLE_SWITCH */ +} - ++ +/* + * ipipe_switch_mm_head is reserved to the head domain for switching + * mmu context. @@ -1030,15 +1030,23 @@ index a73668a..a8019f2 100644 } #define deactivate_mm(tsk,mm) do { } while (0) -@@ -99,7 +221,7 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) +@@ -96,11 +218,15 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, + */ + static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) + { ++#ifndef CONFIG_IPIPE unsigned long flags; local_irq_save(flags); - switch_mm(prev, next, current); ++#endif + __switch_mm(prev, next, current); ++#ifndef CONFIG_IPIPE local_irq_restore(flags); ++#endif } + /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index c9f698a..cd4f633 100644 --- a/arch/powerpc/include/asm/mpic.h @@ -1448,7 +1456,7 @@ index ba3aeb4..bab7e1d 100644 * PROM code for specific machines follows. Put it * here so it's easy to add arch-specific sections later. diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S -index 5971c85..b42077d 100644 +index 8d2fa24..013f32e 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -34,6 +34,12 @@ @@ -1562,7 +1570,7 @@ index 5971c85..b42077d 100644 bl .schedule_tail REST_NVGPRS(r1) li r3,0 -@@ -538,6 +607,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) +@@ -549,6 +618,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) addi r1,r1,SWITCH_FRAME_SIZE blr @@ -1577,7 +1585,7 @@ index 5971c85..b42077d 100644 .align 7 _GLOBAL(ret_from_except) ld r11,_TRAP(r1) -@@ -558,6 +635,16 @@ _GLOBAL(ret_from_except_lite) +@@ -569,6 +646,16 @@ _GLOBAL(ret_from_except_lite) mtmsrd r10,1 /* Update machine state */ #endif /* CONFIG_PPC_BOOK3E */ @@ -1594,7 +1602,7 @@ index 5971c85..b42077d 100644 clrrdi r9,r1,THREAD_SHIFT /* current_thread_info() */ ld r3,_MSR(r1) ld r4,TI_FLAGS(r9) -@@ -571,6 +658,9 @@ _GLOBAL(ret_from_except_lite) +@@ -582,6 +669,9 @@ _GLOBAL(ret_from_except_lite) andi. r0,r4,_TIF_NEED_RESCHED beq 1f bl .restore_interrupts @@ -1604,7 +1612,7 @@ index 5971c85..b42077d 100644 bl .schedule b .ret_from_except_lite -@@ -598,7 +688,12 @@ resume_kernel: +@@ -609,7 +699,12 @@ resume_kernel: * sure we are soft-disabled first */ SOFT_DISABLE_INTS(r3,r4) @@ -1618,7 +1626,7 @@ index 5971c85..b42077d 100644 /* Re-test flags and eventually loop */ clrrdi r9,r1,THREAD_SHIFT -@@ -770,12 +865,20 @@ restore_check_irq_replay: +@@ -781,12 +876,20 @@ restore_check_irq_replay: cmpwi cr0,r3,0x500 bne 1f addi r3,r1,STACK_FRAME_OVERHEAD; @@ -1639,7 +1647,7 @@ index 5971c85..b42077d 100644 b .ret_from_except #ifdef CONFIG_PPC_BOOK3E 1: cmpwi cr0,r3,0x280 -@@ -1003,6 +1106,10 @@ _GLOBAL(_mcount) +@@ -1014,6 +1117,10 @@ _GLOBAL(_mcount) blr _GLOBAL(ftrace_caller) @@ -1650,7 +1658,7 @@ index 5971c85..b42077d 100644 /* Taken from output of objdump from lib64/glibc */ mflr r3 ld r11, 0(r1) -@@ -1030,6 +1137,10 @@ _GLOBAL(mcount) +@@ -1041,6 +1148,10 @@ _GLOBAL(mcount) blr _GLOBAL(_mcount) @@ -2639,7 +2647,7 @@ index 3e40315..269223f 100644 #endif diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c -index 710f400..e8fe79b 100644 +index 1a1f2dd..18d073f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -102,8 +102,12 @@ EXPORT_SYMBOL_GPL(flush_fp_to_thread); @@ -2681,7 +2689,7 @@ index 710f400..e8fe79b 100644 return last; } -@@ -1110,6 +1115,7 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, +@@ -1102,6 +1107,7 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, return 0; } @@ -2689,7 +2697,7 @@ index 710f400..e8fe79b 100644 int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { -@@ -1121,6 +1127,13 @@ int validate_sp(unsigned long sp, struct task_struct *p, +@@ -1113,6 +1119,13 @@ int validate_sp(unsigned long sp, struct task_struct *p, return valid_irq_stack(sp, p, nbytes); } @@ -2753,7 +2761,7 @@ index 389bd4f..825cb22 100644 #ifdef CONFIG_PPC_BOOK3E static void __init exc_lvl_early_init(void) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c -index e4cb343..7f5563e 100644 +index 8d7c119..9f22096 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -153,7 +153,7 @@ const char *smp_ipi_name[] = { @@ -2780,7 +2788,7 @@ index e4cb343..7f5563e 100644 #endif err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU | IRQF_NO_THREAD, -@@ -270,8 +270,12 @@ void smp_send_debugger_break(void) +@@ -277,8 +277,12 @@ void smp_send_debugger_break(void) return; for_each_online_cpu(cpu) @@ -2907,7 +2915,7 @@ index be171ee..dbe985d 100644 } diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c -index 1589723..abe9762 100644 +index ae0843f..14ac2f9 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -661,6 +661,9 @@ void machine_check_exception(struct pt_regs *regs) @@ -2957,7 +2965,7 @@ index 1589723..abe9762 100644 if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) return; -@@ -994,6 +1008,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) +@@ -995,6 +1009,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) /* We can now get here via a FP Unavailable exception if the core * has no FPU, in that case the reason flags will be 0 */ @@ -2967,7 +2975,7 @@ index 1589723..abe9762 100644 if (reason & REASON_FP) { /* IEEE FP exception */ parse_fpe(regs); -@@ -1075,6 +1092,9 @@ void alignment_exception(struct pt_regs *regs) +@@ -1076,6 +1093,9 @@ void alignment_exception(struct pt_regs *regs) if (!arch_irq_disabled_regs(regs)) local_irq_enable(); @@ -2977,7 +2985,7 @@ index 1589723..abe9762 100644 /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs); -@@ -1112,6 +1132,8 @@ void nonrecoverable_exception(struct pt_regs *regs) +@@ -1113,6 +1133,8 @@ void nonrecoverable_exception(struct pt_regs *regs) { printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n", regs->nip, regs->msr); @@ -2986,7 +2994,7 @@ index 1589723..abe9762 100644 debugger(regs); die("nonrecoverable exception", regs, SIGKILL); } -@@ -1127,11 +1149,16 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) +@@ -1128,11 +1150,16 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) { printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); @@ -3003,7 +3011,7 @@ index 1589723..abe9762 100644 if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ -@@ -1174,6 +1201,9 @@ void SoftwareEmulation(struct pt_regs *regs) +@@ -1175,6 +1202,9 @@ void SoftwareEmulation(struct pt_regs *regs) int errcode; #endif @@ -3013,7 +3021,7 @@ index 1589723..abe9762 100644 CHECK_FULL_REGS(regs); if (!user_mode(regs)) { -@@ -1287,6 +1317,9 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) +@@ -1288,6 +1318,9 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status) void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) { @@ -3023,7 +3031,7 @@ index 1589723..abe9762 100644 current->thread.dbsr = debug_status; /* Hack alert: On BookE, Branch Taken stops on the branch itself, while -@@ -1361,6 +1394,9 @@ void altivec_assist_exception(struct pt_regs *regs) +@@ -1362,6 +1395,9 @@ void altivec_assist_exception(struct pt_regs *regs) { int err; @@ -3033,7 +3041,7 @@ index 1589723..abe9762 100644 if (!user_mode(regs)) { printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode" " at %lx\n", regs->nip); -@@ -1413,8 +1449,11 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address, +@@ -1414,8 +1450,11 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address, * as priv ops, in the future we could try to do * something smarter */ @@ -3046,7 +3054,7 @@ index 1589723..abe9762 100644 return; } #endif /* CONFIG_FSL_BOOKE */ -@@ -1473,6 +1512,9 @@ void SPEFloatingPointRoundException(struct pt_regs *regs) +@@ -1474,6 +1513,9 @@ void SPEFloatingPointRoundException(struct pt_regs *regs) extern int speround_handler(struct pt_regs *regs); int err; @@ -3056,7 +3064,7 @@ index 1589723..abe9762 100644 preempt_disable(); if (regs->msr & MSR_SPE) giveup_spe(current); -@@ -1510,6 +1552,8 @@ void unrecoverable_exception(struct pt_regs *regs) +@@ -1511,6 +1553,8 @@ void unrecoverable_exception(struct pt_regs *regs) { printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n", regs->trap, regs->nip); @@ -4773,17 +4781,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]; @@ -4804,7 +4840,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 @@ -4816,16 +4852,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 @@ -4980,6 +5016,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 @@ -5149,10 +5199,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 + * @@ -5223,6 +5273,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 @@ -5468,31 +5519,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; ++ ++ desc = irq_to_desc(irq); ++ if (desc == NULL) ++ return; ++ ++ chip = irq_desc_get_chip(desc); + -+ if (WARN_ON_ONCE(chip->irq_unmask == NULL)) ++ if (WARN_ON_ONCE(chip->irq_enable == NULL && chip->irq_unmask == NULL)) + return; + -+ chip->irq_unmask(&desc->irq_data); ++ 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) @@ -7388,7 +7458,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 { @@ -7444,7 +7514,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; @@ -7455,7 +7525,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 */ @@ -7730,10 +7800,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); @@ -7819,7 +7889,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) @@ -7919,7 +7989,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 @@ @@ -7949,8 +8019,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--- @@ -8303,10 +8373,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 + * @@ -9157,7 +9227,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))) @@ -9192,7 +9264,9 @@ index 0000000..b0af234 +{ + unsigned long flags; + ++#ifndef CONFIG_IPIPE_LEGACY + ipipe_root_only(); ++#endif /* CONFIG_IPIPE_LEGACY */ + + spin_lock_irqsave(&__ipipe_lock, flags); + @@ -9371,25 +9445,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); @@ -9404,12 +9503,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) @@ -9453,18 +9550,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()); + } + + /* @@ -10014,10 +10112,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 + * @@ -10350,6 +10448,7 @@ index 0000000..9a076ab +{ + struct clock_event_device *evtdev; + struct ipipe_timer *timer; ++ struct irq_desc *desc; + unsigned long flags; + int steal, ret; + @@ -10389,10 +10488,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; +} + @@ -10401,15 +10500,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) { @@ -11947,7 +12048,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 @@ @@ -12080,7 +12181,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); @@ -12210,11 +12311,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; } @@ -12597,7 +12699,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) @@ -12667,7 +12769,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) { @@ -12675,7 +12777,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) { @@ -12683,7 +12785,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. */ @@ -12692,7 +12794,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; @@ -12703,7 +12805,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; @@ -12713,7 +12815,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); @@ -12733,7 +12835,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); @@ -12743,7 +12845,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; @@ -12752,7 +12854,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); @@ -12760,7 +12862,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; @@ -12768,7 +12870,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 */ @@ -12781,6 +12883,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); @@ -12988,10 +13092,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++; } @@ -13000,7 +13104,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++; } @@ -13010,10 +13114,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); } @@ -13193,8 +13297,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: @@ -13271,7 +13387,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) @@ -13279,7 +13395,7 @@ index 2466d12..ab93d65 100644 + do_cow_break = 0; + } +#else - again: ++again: +#endif init_rss_vec(rss); @@ -13353,92 +13469,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; @@ -13471,6 +13508,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 @@ -13496,61 +13572,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