Module: xenomai-3
Branch: stable-3.0.x
Commit: 2eae1185f359e6da8746333077d38e194352d805
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=2eae1185f359e6da8746333077d38e194352d805

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Sep  9 18:55:43 2016 +0200

cobalt/arm: upgrade I-pipe support

---

 ...arm-9.patch => ipipe-core-3.18.20-arm-11.patch} |  342 +++++++++++++-
 ...8-arm-4.patch => ipipe-core-4.1.18-arm-8.patch} |  487 +++++++++++++++-----
 2 files changed, 704 insertions(+), 125 deletions(-)

diff --git a/kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-9.patch 
b/kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-11.patch
similarity index 98%
rename from kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-9.patch
rename to kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-11.patch
index d594401..efe7c8f 100644
--- a/kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-9.patch
+++ b/kernel/cobalt/arch/arm/patches/ipipe-core-3.18.20-arm-11.patch
@@ -1,5 +1,5 @@
 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 89c4b5c..46ec8f8 100644
+index 89c4b5c..6b13805 100644
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
 @@ -33,8 +33,8 @@ config ARM
@@ -80,6 +80,14 @@ index 89c4b5c..46ec8f8 100644
  source kernel/Kconfig.preempt
  
  config HZ_FIXED
+@@ -1741,6 +1760,7 @@ config ALIGNMENT_TRAP
+ config UACCESS_WITH_MEMCPY
+       bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()"
+       depends on MMU
++      depends on !IPIPE
+       default y if CPU_FEROCEON
+       help
+         Implement faster copy_to_user and clear_user methods for CPU
 diff --git a/arch/arm/boot/compressed/decompress.c 
b/arch/arm/boot/compressed/decompress.c
 index bd245d3..65f2238 100644
 --- a/arch/arm/boot/compressed/decompress.c
@@ -1653,7 +1661,7 @@ index bb28af7..780ca50 100644
  static inline void sp804_clockevents_init(void __iomem *base, unsigned int 
irq, const char *name)
 diff --git a/arch/arm/include/asm/ipipe.h b/arch/arm/include/asm/ipipe.h
 new file mode 100644
-index 0000000..d1c125d
+index 0000000..5ec5eff
 --- /dev/null
 +++ b/arch/arm/include/asm/ipipe.h
 @@ -0,0 +1,272 @@
@@ -1701,7 +1709,7 @@ index 0000000..d1c125d
 +#include <linux/jump_label.h>
 +#include <linux/ipipe_trace.h>
 +
-+#define IPIPE_CORE_RELEASE    9
++#define IPIPE_CORE_RELEASE    11
 +
 +struct ipipe_domain;
 +
@@ -4301,10 +4309,10 @@ index 0000000..8024a79
 +EXPORT_SYMBOL_GPL(cpu_architecture);
 diff --git a/arch/arm/kernel/ipipe_tsc.c b/arch/arm/kernel/ipipe_tsc.c
 new file mode 100644
-index 0000000..414ada5
+index 0000000..6bcabb3
 --- /dev/null
 +++ b/arch/arm/kernel/ipipe_tsc.c
-@@ -0,0 +1,203 @@
+@@ -0,0 +1,207 @@
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
@@ -4378,6 +4386,10 @@ index 0000000..414ada5
 +      tsc_addr = &__ipipe_tsc_addr;
 +#endif
 +      registered = ipipe_tsc_value != NULL;
++
++      if (registered && info->freq < tsc_info.freq)
++              return;
++
 +      ipipe_tsc_value = (struct ipipe_tsc_value_t *)tsc_area;
 +      vector_tsc_value = (struct ipipe_tsc_value_t *)__ipipe_tsc_area;
 +
@@ -7090,7 +7102,7 @@ index 5211f62..c0a8610 100644
        platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
                                        ARRAY_SIZE(imx25_audmux_res));
 diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
-index 7d82a5a..9bbd0f4 100644
+index 7d82a5a5..9bbd0f4 100644
 --- a/arch/arm/mach-imx/mm-imx27.c
 +++ b/arch/arm/mach-imx/mm-imx27.c
 @@ -81,6 +81,10 @@ static const struct resource imx27_audmux_res[] __initconst 
= {
@@ -12308,6 +12320,85 @@ index 9f06825..1087ed1 100644
                                irq_find_mapping(d->irq_domain,
                                                 d->chip.base + bit));
                }
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index a93ddbc..7c74176 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -295,10 +295,11 @@ static void mvebu_gpio_irq_ack(struct irq_data *d)
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct mvebu_gpio_chip *mvchip = gc->private;
+       u32 mask = ~(1 << (d->irq - gc->irq_base));
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       writel_relaxed(mask, mvebu_gpioreg_edge_cause(mvchip));
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
+@@ -307,12 +308,13 @@ static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
+       struct mvebu_gpio_chip *mvchip = gc->private;
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+       u32 mask = 1 << (d->irq - gc->irq_base);
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       ct->mask_cache_priv &= ~mask;
+ 
+       writel_relaxed(ct->mask_cache_priv, mvebu_gpioreg_edge_mask(mvchip));
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
+@@ -322,11 +324,12 @@ static void mvebu_gpio_edge_irq_unmask(struct irq_data 
*d)
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ 
+       u32 mask = 1 << (d->irq - gc->irq_base);
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       ct->mask_cache_priv |= mask;
+       writel_relaxed(ct->mask_cache_priv, mvebu_gpioreg_edge_mask(mvchip));
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void mvebu_gpio_level_irq_mask(struct irq_data *d)
+@@ -336,11 +339,12 @@ static void mvebu_gpio_level_irq_mask(struct irq_data *d)
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ 
+       u32 mask = 1 << (d->irq - gc->irq_base);
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       ct->mask_cache_priv &= ~mask;
+       writel_relaxed(ct->mask_cache_priv, mvebu_gpioreg_level_mask(mvchip));
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
+@@ -350,11 +354,12 @@ static void mvebu_gpio_level_irq_unmask(struct irq_data 
*d)
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ 
+       u32 mask = 1 << (d->irq - gc->irq_base);
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       ct->mask_cache_priv |= mask;
+       writel_relaxed(ct->mask_cache_priv, mvebu_gpioreg_level_mask(mvchip));
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ /*****************************************************************************
 diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
 index f4e54a9..8818bc3 100644
 --- a/drivers/gpio/gpio-mxc.c
@@ -13212,6 +13303,86 @@ index a11aae8..ec094e1 100644
                gc->chip_types[0].chip.irq_retrigger = aic5_retrigger;
                gc->chip_types[0].chip.irq_set_type = aic5_set_type;
                gc->chip_types[0].chip.irq_suspend = aic5_suspend;
+diff --git a/drivers/irqchip/irq-bcm7120-l2.c 
b/drivers/irqchip/irq-bcm7120-l2.c
+index 5fb38a2..b2afa17 100644
+--- a/drivers/irqchip/irq-bcm7120-l2.c
++++ b/drivers/irqchip/irq-bcm7120-l2.c
+@@ -71,27 +71,29 @@ static void bcm7120_l2_intc_suspend(struct irq_data *d)
+ {
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct bcm7120_l2_intc_data *b = gc->private;
++      unsigned long flags;
+       u32 reg;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       /* Save the current mask and the interrupt forward mask */
+       b->saved_mask = __raw_readl(b->base) | b->irq_fwd_mask;
+       if (b->can_wake) {
+               reg = b->saved_mask | gc->wake_active;
+               __raw_writel(reg, b->base);
+       }
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void bcm7120_l2_intc_resume(struct irq_data *d)
+ {
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct bcm7120_l2_intc_data *b = gc->private;
++      unsigned long flags;
+ 
+       /* Restore the saved mask */
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       __raw_writel(b->saved_mask, b->base);
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static int bcm7120_l2_intc_init_one(struct device_node *dn,
+diff --git a/drivers/irqchip/irq-brcmstb-l2.c 
b/drivers/irqchip/irq-brcmstb-l2.c
+index 14691a4..31db906 100644
+--- a/drivers/irqchip/irq-brcmstb-l2.c
++++ b/drivers/irqchip/irq-brcmstb-l2.c
+@@ -82,8 +82,9 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
+ {
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct brcmstb_l2_intc_data *b = gc->private;
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       /* Save the current mask */
+       b->saved_mask = __raw_readl(b->base + CPU_MASK_STATUS);
+ 
+@@ -92,22 +93,23 @@ static void brcmstb_l2_intc_suspend(struct irq_data *d)
+               __raw_writel(~gc->wake_active, b->base + CPU_MASK_SET);
+               __raw_writel(gc->wake_active, b->base + CPU_MASK_CLEAR);
+       }
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ static void brcmstb_l2_intc_resume(struct irq_data *d)
+ {
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct brcmstb_l2_intc_data *b = gc->private;
++      unsigned long flags;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+       /* Clear unmasked non-wakeup interrupts */
+       __raw_writel(~b->saved_mask & ~gc->wake_active, b->base + CPU_CLEAR);
+ 
+       /* Restore the saved mask */
+       __raw_writel(b->saved_mask, b->base + CPU_MASK_SET);
+       __raw_writel(~b->saved_mask, b->base + CPU_MASK_CLEAR);
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ }
+ 
+ int __init brcmstb_l2_intc_of_init(struct device_node *np,
 diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
 index 38493ff..fbc428b 100644
 --- a/drivers/irqchip/irq-gic.c
@@ -13645,6 +13816,40 @@ index c8d373f..1f81463 100644
        }
  
        chained_irq_exit(chip, desc);
+diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
+index eb9b59e..7cda6c6 100644
+--- a/drivers/irqchip/irq-sunxi-nmi.c
++++ b/drivers/irqchip/irq-sunxi-nmi.c
+@@ -76,9 +76,10 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, 
unsigned int flow_type)
+       u32 src_type_reg;
+       u32 ctrl_off = ct->regs.type;
+       unsigned int src_type;
++      unsigned long flags;
+       unsigned int i;
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+ 
+       switch (flow_type & IRQF_TRIGGER_MASK) {
+       case IRQ_TYPE_EDGE_FALLING:
+@@ -95,7 +96,7 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, 
unsigned int flow_type)
+               src_type = SUNXI_SRC_TYPE_LEVEL_LOW;
+               break;
+       default:
+-              irq_gc_unlock(gc);
++              irq_gc_unlock(gc, flags);
+               pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
+                       __func__, data->irq);
+               return -EBADR;
+@@ -113,7 +114,7 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, 
unsigned int flow_type)
+       src_type_reg |= src_type;
+       sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg);
+ 
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ 
+       return IRQ_SET_MASK_OK;
+ }
 diff --git a/drivers/irqchip/irq-versatile-fpga.c 
b/drivers/irqchip/irq-versatile-fpga.c
 index 1ab4517..31d698a 100644
 --- a/drivers/irqchip/irq-versatile-fpga.c
@@ -13830,6 +14035,65 @@ index bbeb451..48db51f 100644
  
  config SENSORS_APDS990X
         tristate "APDS990X combined als and proximity sensors"
+diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
+index d6380c1..6ee894b 100644
+--- a/drivers/pinctrl/pinctrl-at91.c
++++ b/drivers/pinctrl/pinctrl-at91.c
+@@ -18,6 +18,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
+ #include <linux/gpio.h>
++#include <linux/ipipe.h>
+ #include <linux/pinctrl/machine.h>
+ #include <linux/pinctrl/pinconf.h>
+ #include <linux/pinctrl/pinctrl.h>
+@@ -1615,7 +1616,7 @@ static void gpio_irq_handler(unsigned irq, struct 
irq_desc *desc)
+               }
+ 
+               for_each_set_bit(n, &isr, BITS_PER_LONG) {
+-                      generic_handle_irq(irq_find_mapping(
++                      ipipe_handle_demuxed_irq(irq_find_mapping(
+                                          gpio_chip->irqdomain, n));
+               }
+       }
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c 
b/drivers/pinctrl/pinctrl-rockchip.c
+index 016f457..00159d1 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -1446,6 +1446,7 @@ static int rockchip_irq_set_type(struct irq_data *d, 
unsigned int type)
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct rockchip_pin_bank *bank = gc->private;
+       u32 mask = BIT(d->hwirq);
++      unsigned long flags;
+       u32 polarity;
+       u32 level;
+       u32 data;
+@@ -1465,7 +1466,7 @@ static int rockchip_irq_set_type(struct irq_data *d, 
unsigned int type)
+       else
+               __irq_set_handler_locked(d->irq, handle_level_irq);
+ 
+-      irq_gc_lock(gc);
++      flags = irq_gc_lock(gc);
+ 
+       level = readl_relaxed(gc->reg_base + GPIO_INTTYPE_LEVEL);
+       polarity = readl_relaxed(gc->reg_base + GPIO_INT_POLARITY);
+@@ -1506,14 +1507,14 @@ static int rockchip_irq_set_type(struct irq_data *d, 
unsigned int type)
+               polarity &= ~mask;
+               break;
+       default:
+-              irq_gc_unlock(gc);
++              irq_gc_unlock(gc, flags);
+               return -EINVAL;
+       }
+ 
+       writel_relaxed(level, gc->reg_base + GPIO_INTTYPE_LEVEL);
+       writel_relaxed(polarity, gc->reg_base + GPIO_INT_POLARITY);
+ 
+-      irq_gc_unlock(gc);
++      irq_gc_unlock(gc, flags);
+ 
+       return 0;
+ }
 diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
 index c5029c1..2d68014 100644
 --- a/drivers/cpuidle/Kconfig
@@ -14264,6 +14528,18 @@ index abcafaa..a8440e4 100644
  } ____cacheline_aligned;
  
  /*
+diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
+index 662697b..6a9b6ad 100644
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -108,6 +108,7 @@ enum {
+       FTRACE_OPS_FL_ADDING                    = 1 << 9,
+       FTRACE_OPS_FL_REMOVING                  = 1 << 10,
+       FTRACE_OPS_FL_MODIFYING                 = 1 << 11,
++      FTRACE_OPS_FL_IPIPE_EXCLUSIVE           = 1 << 12,
+ };
+ 
+ #ifdef CONFIG_DYNAMIC_FTRACE
 diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
 index cba442e..b513a46 100644
 --- a/include/linux/hardirq.h
@@ -20209,7 +20485,7 @@ index 0000000..143f9e6
 +#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..da272c50
+index 0000000..8388671
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
 @@ -0,0 +1,1468 @@
@@ -21547,7 +21823,7 @@ index 0000000..da272c50
 +
 +static struct ftrace_ops ipipe_trace_ops = {
 +      .func = ipipe_trace_function,
-+      .flags = FTRACE_OPS_FL_RECURSION_SAFE,
++      .flags = FTRACE_OPS_FL_IPIPE_EXCLUSIVE,
 +};
 +
 +static ssize_t __ipipe_wr_enable(struct file *file, const char __user *buffer,
@@ -23108,7 +23384,7 @@ index a5da09c..6650799 100644
        help
          This option will modify all the calls to function tracing
 diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
-index d1eff3d..2a324bc 100644
+index d1eff3d..f8b9472 100644
 --- a/kernel/trace/ftrace.c
 +++ b/kernel/trace/ftrace.c
 @@ -32,6 +32,7 @@
@@ -23119,7 +23395,33 @@ index d1eff3d..2a324bc 100644
  
  #include <trace/events/sched.h>
  
-@@ -2298,6 +2299,9 @@ void __weak arch_ftrace_update_code(int command)
+@@ -251,8 +252,17 @@ static inline void update_function_graph_func(void) { }
+ 
+ static void update_ftrace_function(void)
+ {
++      struct ftrace_ops *ops;
+       ftrace_func_t func;
+ 
++      for (ops = ftrace_ops_list;
++           ops != &ftrace_list_end; ops = ops->next)
++              if (ops->flags & FTRACE_OPS_FL_IPIPE_EXCLUSIVE) {
++                      set_function_trace_op = ops;
++                      func = ops->func;
++                      goto set_pointers;
++              }
++
+       /*
+        * Prepare the ftrace_ops that the arch callback will use.
+        * If there's only one ftrace_ops registered, the ftrace_ops_list
+@@ -280,6 +290,7 @@ static void update_ftrace_function(void)
+ 
+       update_function_graph_func();
+ 
++  set_pointers:
+       /* If there's no change, then do nothing more here */
+       if (ftrace_trace_function == func)
+               return;
+@@ -2298,6 +2309,9 @@ void __weak arch_ftrace_update_code(int command)
  
  static void ftrace_run_update_code(int command)
  {
@@ -23129,7 +23431,7 @@ index d1eff3d..2a324bc 100644
        int ret;
  
        ret = ftrace_arch_code_modify_prepare();
-@@ -2311,7 +2315,13 @@ static void ftrace_run_update_code(int command)
+@@ -2311,7 +2325,13 @@ static void ftrace_run_update_code(int command)
         * is safe. The stop_machine() is the safest, but also
         * produces the most overhead.
         */
@@ -23143,7 +23445,7 @@ index d1eff3d..2a324bc 100644
  
        ret = ftrace_arch_code_modify_post_process();
        FTRACE_WARN_ON(ret);
-@@ -4621,10 +4631,10 @@ static int ftrace_process_locs(struct module *mod,
+@@ -4621,10 +4641,10 @@ static int ftrace_process_locs(struct module *mod,
         * reason to cause large interrupt latencies while we do it.
         */
        if (!mod)
@@ -23156,7 +23458,7 @@ index d1eff3d..2a324bc 100644
        ret = 0;
   out:
        mutex_unlock(&ftrace_lock);
-@@ -4723,9 +4733,11 @@ void __init ftrace_init(void)
+@@ -4723,9 +4743,11 @@ void __init ftrace_init(void)
        unsigned long count, flags;
        int ret;
  
@@ -23170,7 +23472,7 @@ index d1eff3d..2a324bc 100644
        if (ret)
                goto failed;
  
-@@ -4891,7 +4903,16 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long 
parent_ip,
+@@ -4891,7 +4913,16 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long 
parent_ip,
                }
        } while_for_each_ftrace_op(op);
  out:
@@ -23536,24 +23838,22 @@ index 0c9216c..00a9a30 100644
        return err;
  }
 diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
-index 1afec32..5803111 100644
+index 1afec32..f7c1a2a 100644
 --- a/lib/smp_processor_id.c
 +++ b/lib/smp_processor_id.c
-@@ -12,10 +12,13 @@ notrace static unsigned int 
check_preemption_disabled(const char *what1,
+@@ -12,6 +12,12 @@ notrace static unsigned int check_preemption_disabled(const 
char *what1,
  {
        int this_cpu = raw_smp_processor_id();
  
++      if (hard_irqs_disabled())
++              goto out;
++
 +      if (!ipipe_root_p)
 +              goto out;
 +
        if (likely(preempt_count()))
                goto out;
  
--      if (irqs_disabled())
-+      if (irqs_disabled() || hard_irqs_disabled())
-               goto out;
- 
-       /*
 diff --git a/mm/memory.c b/mm/memory.c
 index 90fb265..8a1fd79 100644
 --- a/mm/memory.c
diff --git a/kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-4.patch 
b/kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-8.patch
similarity index 98%
rename from kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-4.patch
rename to kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-8.patch
index f8e3c73..cfdbcc6 100644
--- a/kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-4.patch
+++ b/kernel/cobalt/arch/arm/patches/ipipe-core-4.1.18-arm-8.patch
@@ -1,5 +1,5 @@
 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 19f4cc6..dc88360 100644
+index 19f4cc6..6bdc70c 100644
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
 @@ -36,8 +36,8 @@ config ARM
@@ -60,6 +60,14 @@ index 19f4cc6..dc88360 100644
  source kernel/Kconfig.preempt
  
  config HZ_FIXED
+@@ -1718,6 +1731,7 @@ config ALIGNMENT_TRAP
+ config UACCESS_WITH_MEMCPY
+       bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()"
+       depends on MMU
++      depends on !IPIPE
+       default y if CPU_FEROCEON
+       help
+         Implement faster copy_to_user and clear_user methods for CPU
 diff --git a/arch/arm/boot/compressed/decompress.c 
b/arch/arm/boot/compressed/decompress.c
 index a0765e7..381ad50 100644
 --- a/arch/arm/boot/compressed/decompress.c
@@ -1635,10 +1643,10 @@ index bb28af7..780ca50 100644
  static inline void sp804_clockevents_init(void __iomem *base, unsigned int 
irq, const char *name)
 diff --git a/arch/arm/include/asm/ipipe.h b/arch/arm/include/asm/ipipe.h
 new file mode 100644
-index 0000000..df05570
+index 0000000..ebda70c
 --- /dev/null
 +++ b/arch/arm/include/asm/ipipe.h
-@@ -0,0 +1,297 @@
+@@ -0,0 +1,298 @@
 +/* -*- linux-c -*-
 + * arch/arm/include/asm/ipipe.h
 + *
@@ -1685,7 +1693,7 @@ index 0000000..df05570
 +#include <linux/jump_label.h>
 +#include <linux/ipipe_trace.h>
 +
-+#define IPIPE_CORE_RELEASE    4
++#define IPIPE_CORE_RELEASE    8
 +
 +struct ipipe_domain;
 +struct timekeeper;
@@ -1720,6 +1728,7 @@ index 0000000..df05570
 +                      unsigned long long *tsc; /* 64 bits tsc value. */
 +              } dec;
 +      } u;
++      unsigned int (*refresh_freq)(void);
 +};
 +
 +struct ipipe_arch_sysinfo {
@@ -4277,17 +4286,17 @@ index 0000000..ffe02fe
 +EXPORT_SYMBOL_GPL(cpu_architecture);
 diff --git a/arch/arm/kernel/ipipe_tsc.c b/arch/arm/kernel/ipipe_tsc.c
 new file mode 100644
-index 0000000..aa9571e
+index 0000000..6f9cff8
 --- /dev/null
 +++ b/arch/arm/kernel/ipipe_tsc.c
-@@ -0,0 +1,214 @@
+@@ -0,0 +1,265 @@
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/sched.h>
 +#include <linux/timer.h>
 +#include <linux/clocksource.h>
 +#include <linux/ipipe_tickdev.h>
-+
++#include <linux/cpufreq.h>
 +#include <linux/ipipe.h>
 +
 +#include <asm/cacheflush.h>
@@ -4495,6 +4504,57 @@ index 0000000..aa9571e
 +{
 +}
 +#endif
++
++#ifdef CONFIG_CPU_FREQ
++
++static __init void update_timer_freq(void *data)
++{
++      unsigned int hrclock_freq = *(unsigned int *)data;
++
++      __ipipe_timer_refresh_freq(hrclock_freq);
++}
++
++static __init int cpufreq_transition_handler(struct notifier_block *nb,
++                                    unsigned long state, void *data)
++{
++      struct cpufreq_freqs *freqs = data;
++      unsigned int freq;
++
++      if (state == CPUFREQ_POSTCHANGE && tsc_info.refresh_freq) {
++              freq = tsc_info.refresh_freq();
++              if (freqs->cpu == 0) {
++                      tsc_info.freq = freq;
++                      __ipipe_tsc_register(&tsc_info);
++                      __ipipe_report_clockfreq_update(freq);
++              }
++              smp_call_function_single(freqs->cpu, update_timer_freq,
++                                       &freq, 1);
++      }
++
++      return NOTIFY_OK;
++}
++
++static struct notifier_block __initdata cpufreq_nb = {
++      .notifier_call = cpufreq_transition_handler,
++};
++
++static __init int register_cpufreq_notifier(void)
++{
++      cpufreq_register_notifier(&cpufreq_nb,
++                                CPUFREQ_TRANSITION_NOTIFIER);
++      return 0;
++}
++core_initcall(register_cpufreq_notifier);
++
++static __init int unregister_cpufreq_notifier(void)
++{
++      cpufreq_unregister_notifier(&cpufreq_nb,
++                                CPUFREQ_TRANSITION_NOTIFIER);
++      return 0;
++}
++late_initcall(unregister_cpufreq_notifier);
++
++#endif /* CONFIG_CPUFREQ */
 diff --git a/arch/arm/kernel/ipipe_tsc_asm.S b/arch/arm/kernel/ipipe_tsc_asm.S
 new file mode 100644
 index 0000000..3f0999d
@@ -5211,7 +5271,7 @@ index f11d825..68981b8 100644
  
        default:
 diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
-index 172c6a05..6d41146 100644
+index 172c6a05..64c3c5c 100644
 --- a/arch/arm/kernel/smp_twd.c
 +++ b/arch/arm/kernel/smp_twd.c
 @@ -20,14 +20,19 @@
@@ -5273,7 +5333,21 @@ index 172c6a05..6d41146 100644
  static void twd_set_mode(enum clock_event_mode mode,
                        struct clock_event_device *clk)
  {
-@@ -232,7 +269,11 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
+@@ -189,6 +226,13 @@ core_initcall(twd_cpufreq_init);
+ 
+ #endif
+ 
++#ifdef CONFIG_IPIPE
++static unsigned int twd_refresh_freq(void)
++{
++      return clk_get_rate(twd_clk);
++}
++#endif
++
+ static void twd_calibrate_rate(void)
+ {
+       unsigned long count;
+@@ -232,7 +276,11 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
  {
        struct clock_event_device *evt = dev_id;
  
@@ -5285,7 +5359,7 @@ index 172c6a05..6d41146 100644
                evt->event_handler(evt);
                return IRQ_HANDLED;
        }
-@@ -299,6 +340,17 @@ static void twd_timer_setup(void)
+@@ -299,6 +347,18 @@ static void twd_timer_setup(void)
        clk->set_mode = twd_set_mode;
        clk->set_next_event = twd_set_next_event;
        clk->irq = twd_ppi;
@@ -5298,12 +5372,13 @@ index 172c6a05..6d41146 100644
 +      clk->ipipe_timer->irq = clk->irq;
 +      clk->ipipe_timer->ack = twd_ack;
 +      clk->ipipe_timer->min_delay_ticks = 0xf;
++      clk->ipipe_timer->refresh_freq = twd_refresh_freq;
 +#endif
 +
        clk->cpumask = cpumask_of(cpu);
  
        clockevents_config_and_register(clk, twd_timer_rate,
-@@ -357,6 +409,10 @@ static int __init twd_local_timer_common_register(struct 
device_node *np)
+@@ -357,6 +417,10 @@ static int __init twd_local_timer_common_register(struct 
device_node *np)
        else
                late_time_init = twd_timer_setup;
  
@@ -5314,7 +5389,7 @@ index 172c6a05..6d41146 100644
        return 0;
  
  out_irq:
-@@ -380,6 +436,7 @@ int __init twd_local_timer_register(struct twd_local_timer 
*tlt)
+@@ -380,6 +444,7 @@ int __init twd_local_timer_register(struct twd_local_timer 
*tlt)
        if (!twd_base)
                return -ENOMEM;
  
@@ -5322,7 +5397,7 @@ index 172c6a05..6d41146 100644
        return twd_local_timer_common_register(NULL);
  }
  
-@@ -403,6 +460,7 @@ static void __init twd_local_timer_of_register(struct 
device_node *np)
+@@ -403,6 +468,7 @@ static void __init twd_local_timer_of_register(struct 
device_node *np)
                goto out;
        }
  
@@ -6569,7 +6644,7 @@ index e065fed..64c026b 100644
  #include <asm/mach/map.h>
  
 diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
-index 7d82a5a..9bbd0f4 100644
+index 7d82a5a5..9bbd0f4 100644
 --- a/arch/arm/mach-imx/mm-imx27.c
 +++ b/arch/arm/mach-imx/mm-imx27.c
 @@ -81,6 +81,10 @@ static const struct resource imx27_audmux_res[] __initconst 
= {
@@ -8992,7 +9067,7 @@ index 9769f1e..c3a4a6f 100644
                        set_cr(cr_no_alignment);
        }
 diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
-index e309c8f..7053f1b 100644
+index e309c8f..48b9211 100644
 --- a/arch/arm/mm/cache-l2x0.c
 +++ b/arch/arm/mm/cache-l2x0.c
 @@ -23,6 +23,7 @@
@@ -9003,7 +9078,7 @@ index e309c8f..7053f1b 100644
  #include <linux/of.h>
  #include <linux/of_address.h>
  
-@@ -47,9 +48,22 @@ struct l2c_init_data {
+@@ -47,9 +48,23 @@ struct l2c_init_data {
  
  #define CACHE_LINE_SIZE               32
  
@@ -9018,6 +9093,7 @@ index e309c8f..7053f1b 100644
 +early_param("l2x0_write_allocate", l2x0_setup_wa);
 +#else
 +#define CACHE_RANGE_ATOMIC_MAX        4096UL
++static int l2x0_wa = 1;
 +#endif
 +
  static void __iomem *l2x0_base;
@@ -9027,7 +9103,7 @@ index e309c8f..7053f1b 100644
  static u32 l2x0_way_mask;     /* Bitmask of active ways */
  static u32 l2x0_size;
  static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
-@@ -292,10 +306,10 @@ static void l2c220_op_way(void __iomem *base, unsigned 
reg)
+@@ -292,10 +307,10 @@ static void l2c220_op_way(void __iomem *base, unsigned 
reg)
  static unsigned long l2c220_op_pa_range(void __iomem *reg, unsigned long 
start,
        unsigned long end, unsigned long flags)
  {
@@ -9040,7 +9116,7 @@ index e309c8f..7053f1b 100644
  
                while (start < blk_end) {
                        l2c_wait_mask(reg, 1);
-@@ -498,13 +512,13 @@ static void l2c310_inv_range_erratum(unsigned long 
start, unsigned long end)
+@@ -498,13 +513,13 @@ static void l2c310_inv_range_erratum(unsigned long 
start, unsigned long end)
  
  static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
  {
@@ -9056,24 +9132,30 @@ index e309c8f..7053f1b 100644
  
                l2c_set_debug(base, 0x03);
                while (start < blk_end) {
-@@ -797,6 +811,22 @@ static int __init __l2c_init(const struct l2c_init_data 
*data,
+@@ -797,6 +812,28 @@ static int __init __l2c_init(const struct l2c_init_data 
*data,
        if (aux_val & aux_mask)
                pr_alert("L2C: platform provided aux values permit register 
corruption.\n");
  
 +      if (IS_ENABLED(CONFIG_IPIPE)) {
 +              switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
 +              case L2X0_CACHE_ID_PART_L310:
++                      if ((cache_id & L2X0_CACHE_ID_RTL_MASK)
++                          >= L310_CACHE_ID_RTL_R3P2) {
++                              l2x0_wa = 1;
++                              pr_alert("L2C: I-pipe: revision >= L310-r3p2 
detected, forcing WA.\n");
++                      }
 +              case L2X0_CACHE_ID_PART_L220:
 +                      if (l2x0_wa < 0) {
 +                              l2x0_wa = 0;
 +                              pr_alert("L2C: I-pipe: l2x0_write_allocate= not 
specified, defaults to 0 (disabled).\n");
 +                      }
-+                      aux_mask &= ~L220_AUX_CTRL_FWA_MASK;
-+                      aux_val &= ~L220_AUX_CTRL_FWA_MASK;
-+                      aux_val |= (!l2x0_wa) << L220_AUX_CTRL_FWA_SHIFT;
++                      if (!l2x0_wa) {
++                              aux_mask &= ~L220_AUX_CTRL_FWA_MASK;
++                              aux_val &= ~L220_AUX_CTRL_FWA_MASK;
++                              aux_val |= 1 << L220_AUX_CTRL_FWA_SHIFT;
++                      } else
++                              pr_alert("L2C: I-pipe: write-allocate enabled, 
induces high latencies.\n");
 +              }
-+              if (l2x0_wa)
-+                      pr_alert("L2C: I-pipe: write-allocate enabled, induces 
high latencies.\n");
 +      }
 +
        old_aux = aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
@@ -10925,7 +11007,7 @@ index 0aa135d..c48e8f7 100644
        clocksource_register_hz(&clocksource_counter, arch_timer_rate);
        cyclecounter.mult = clocksource_counter.mult;
 diff --git a/drivers/clocksource/arm_global_timer.c 
b/drivers/clocksource/arm_global_timer.c
-index e683377..b954fc0 100644
+index e683377..d3193ec 100644
 --- a/drivers/clocksource/arm_global_timer.c
 +++ b/drivers/clocksource/arm_global_timer.c
 @@ -24,6 +24,7 @@
@@ -10936,16 +11018,30 @@ index e683377..b954fc0 100644
  
  #define GT_COUNTER0   0x00
  #define GT_COUNTER1   0x04
-@@ -48,6 +49,7 @@
+@@ -48,6 +49,8 @@
   * the units for all operations.
   */
  static void __iomem *gt_base;
 +static unsigned long gt_pbase;
++static struct clk *gt_clk;
  static unsigned long gt_clk_rate;
  static int gt_ppi;
  static struct clock_event_device __percpu *gt_evt;
-@@ -210,6 +212,20 @@ static u64 notrace gt_sched_clock_read(void)
+@@ -208,8 +211,34 @@ static u64 notrace gt_sched_clock_read(void)
+ }
+ #endif
  
++#ifdef CONFIG_IPIPE
++
++static unsigned int refresh_gt_freq(void)
++{
++      gt_clk_rate = clk_get_rate(gt_clk);
++
++      return gt_clk_rate;
++}
++
++#endif
++
  static void __init gt_clocksource_init(void)
  {
 +#ifdef CONFIG_IPIPE
@@ -10959,13 +11055,14 @@ index e683377..b954fc0 100644
 +                              .mask = 0xffffffff,
 +                      }
 +              },
++              .refresh_freq = refresh_gt_freq,
 +      };
 +#endif
 +
        writel(0, gt_base + GT_CONTROL);
        writel(0, gt_base + GT_COUNTER0);
        writel(0, gt_base + GT_COUNTER1);
-@@ -219,6 +235,9 @@ static void __init gt_clocksource_init(void)
+@@ -219,6 +248,9 @@ static void __init gt_clocksource_init(void)
  #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
        sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate);
  #endif
@@ -10975,18 +11072,18 @@ index e683377..b954fc0 100644
        clocksource_register_hz(&gt_clocksource, gt_clk_rate);
  }
  
-@@ -242,8 +261,9 @@ static struct notifier_block gt_cpu_nb = {
+@@ -242,8 +274,8 @@ static struct notifier_block gt_cpu_nb = {
  
  static void __init global_timer_of_register(struct device_node *np)
  {
+-      struct clk *gt_clk;
+-      int err = 0;
 +      int err = 0, usable_timer = 1;
 +      struct resource res;
-       struct clk *gt_clk;
--      int err = 0;
  
        /*
         * In A9 r2p0 the comparators for each processor with the global timer
-@@ -253,13 +273,15 @@ static void __init global_timer_of_register(struct 
device_node *np)
+@@ -253,13 +285,15 @@ static void __init global_timer_of_register(struct 
device_node *np)
        if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9
            && (read_cpuid_id() & 0xf0000f) < 0x200000) {
                pr_warn("global-timer: non support for this cpu version.\n");
@@ -11007,7 +11104,7 @@ index e683377..b954fc0 100644
        }
  
        gt_base = of_iomap(np, 0);
-@@ -268,6 +290,11 @@ static void __init global_timer_of_register(struct 
device_node *np)
+@@ -268,6 +302,11 @@ static void __init global_timer_of_register(struct 
device_node *np)
                return;
        }
  
@@ -11019,7 +11116,7 @@ index e683377..b954fc0 100644
        gt_clk = of_clk_get(np, 0);
        if (!IS_ERR(gt_clk)) {
                err = clk_prepare_enable(gt_clk);
-@@ -280,30 +307,33 @@ static void __init global_timer_of_register(struct 
device_node *np)
+@@ -280,30 +319,33 @@ static void __init global_timer_of_register(struct 
device_node *np)
        }
  
        gt_clk_rate = clk_get_rate(gt_clk);
@@ -12769,6 +12866,29 @@ index d6bcc6b..f3c04de 100644
  }
  
  int __init brcmstb_l2_intc_of_init(struct device_node *np,
+diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
+index c12bb93..8bb1af7 100644
+--- a/drivers/irqchip/irq-crossbar.c
++++ b/drivers/irqchip/irq-crossbar.c
+@@ -15,6 +15,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/slab.h>
++#include <linux/ipipe.h>
+ 
+ #include "irqchip.h"
+ 
+@@ -74,6 +75,10 @@ static struct irq_chip crossbar_chip = {
+ #ifdef CONFIG_SMP
+       .irq_set_affinity       = irq_chip_set_affinity_parent,
+ #endif
++#ifdef CONFIG_IPIPE
++      .irq_hold               = irq_chip_hold_parent,
++      .irq_release            = irq_chip_release_parent,
++#endif
+ };
+ 
+ static int allocate_gic_irq(struct irq_domain *domain, unsigned virq,
 diff --git a/drivers/irqchip/irq-dw-apb-ictl.c 
b/drivers/irqchip/irq-dw-apb-ictl.c
 index 53bb732..5ca21a2 100644
 --- a/drivers/irqchip/irq-dw-apb-ictl.c
@@ -13575,7 +13695,7 @@ index dee7d5f..f4b5349 100644
  
        return 0;
 diff --git a/drivers/pinctrl/pinctrl-single.c 
b/drivers/pinctrl/pinctrl-single.c
-index 13b45f2..b00fe3a 100644
+index 13b45f2..637f923 100644
 --- a/drivers/pinctrl/pinctrl-single.c
 +++ b/drivers/pinctrl/pinctrl-single.c
 @@ -16,6 +16,7 @@
@@ -13590,11 +13710,10 @@ index 13b45f2..b00fe3a 100644
  #define PCS_FEAT_IRQ          (1 << 1)
  #define PCS_FEAT_PINCONF      (1 << 0)
        struct pcs_soc_data socdata;
--      raw_spinlock_t lock;
 +#ifdef CONFIG_IPIPE
 +      ipipe_spinlock_t lock;
 +#else /* !IPIPE */
-+      raw_spinlock_t lock
+       raw_spinlock_t lock;
 +#endif /* !IPIPE */
        struct mutex mutex;
        unsigned width;
@@ -14075,6 +14194,19 @@ index 0000000..1f6e9c3
 +static inline void __ipipe_init_threadinfo(struct ipipe_threadinfo *p) { }
 +
 +#endif /* !_IPIPE_THREAD_INFO_H */
+diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h
+index 0e97856..b5d7e60 100644
+--- a/include/linux/basic_mmio_gpio.h
++++ b/include/linux/basic_mmio_gpio.h
+@@ -50,7 +50,7 @@ struct bgpio_chip {
+        * Used to lock bgpio_chip->data. Also, this is needed to keep
+        * shadowed and real data registers writes together.
+        */
+-      spinlock_t lock;
++      ipipe_spinlock_t lock;
+ 
+       /* Shadowed data register to clear/set bits safely. */
+       unsigned long data;
 diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
 index 96c280b..0baa8f1 100644
 --- a/include/linux/clockchips.h
@@ -14127,6 +14259,18 @@ index 901555a..1ba117c 100644
        int     (*read)(struct console *, char *, unsigned);
        struct tty_driver *(*device)(struct console *, int *);
        void    (*unblank)(void);
+diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
+index 6cd8c0e..0951ab4 100644
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -134,6 +134,7 @@ enum {
+       FTRACE_OPS_FL_ALLOC_TRAMP               = 1 << 12,
+       FTRACE_OPS_FL_IPMODIFY                  = 1 << 13,
+       FTRACE_OPS_FL_PID                       = 1 << 14,
++      FTRACE_OPS_FL_IPIPE_EXCLUSIVE           = 1 << 15,
+ };
+ 
+ #ifdef CONFIG_DYNAMIC_FTRACE
 diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
 index f4af034..fa16b8c 100644
 --- a/include/linux/hardirq.h
@@ -14637,10 +14781,10 @@ index 0000000..0a9b5b6
 +#endif        /* !__LINUX_IPIPE_H */
 diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
 new file mode 100644
-index 0000000..8c06eed
+index 0000000..42b368a
 --- /dev/null
 +++ b/include/linux/ipipe_base.h
-@@ -0,0 +1,360 @@
+@@ -0,0 +1,365 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_base.h
 + *
@@ -14751,6 +14895,7 @@ index 0000000..8c06eed
 +#define IPIPE_KEVT_EXIT               4
 +#define IPIPE_KEVT_CLEANUP    5
 +#define IPIPE_KEVT_HOSTRT     6
++#define IPIPE_KEVT_CLOCKFREQ  7
 +
 +struct ipipe_vm_notifier {
 +      void (*handler)(struct ipipe_vm_notifier *nfy);
@@ -14879,6 +15024,9 @@ index 0000000..8c06eed
 +#define __ipipe_report_cleanup(mm)                                    \
 +      __ipipe_notify_kevent(IPIPE_KEVT_CLEANUP, mm)
 +
++#define __ipipe_report_clockfreq_update(freq)                         \
++      __ipipe_notify_kevent(IPIPE_KEVT_CLOCKFREQ, &(freq))
++
 +void __ipipe_notify_vm_preemption(void);
 +
 +void __ipipe_call_mayday(struct pt_regs *regs);
@@ -14898,7 +15046,8 @@ index 0000000..8c06eed
 +#define IPIPE_EVENT_EXIT      (IPIPE_FIRST_EVENT + 4)
 +#define IPIPE_EVENT_CLEANUP   (IPIPE_FIRST_EVENT + 5)
 +#define IPIPE_EVENT_HOSTRT    (IPIPE_FIRST_EVENT + 6)
-+#define IPIPE_EVENT_SYSCALL   (IPIPE_FIRST_EVENT + 7)
++#define IPIPE_EVENT_CLOCKFREQ (IPIPE_FIRST_EVENT + 7)
++#define IPIPE_EVENT_SYSCALL   (IPIPE_FIRST_EVENT + 8)
 +#define IPIPE_LAST_EVENT      IPIPE_EVENT_SYSCALL
 +#define IPIPE_NR_EVENTS               (IPIPE_LAST_EVENT + 1)
 +
@@ -15749,10 +15898,10 @@ index 0000000..d00c56b
 +#endif        /* !__LINUX_IPIPE_DOMAIN_H */
 diff --git a/include/linux/ipipe_lock.h b/include/linux/ipipe_lock.h
 new file mode 100644
-index 0000000..f71d2f1
+index 0000000..a108278
 --- /dev/null
 +++ b/include/linux/ipipe_lock.h
-@@ -0,0 +1,260 @@
+@@ -0,0 +1,327 @@
 +/*   -*- linux-c -*-
 + *   include/linux/ipipe_lock.h
 + *
@@ -15781,22 +15930,87 @@ index 0000000..f71d2f1
 +      arch_spinlock_t arch_lock;
 +} __ipipe_spinlock_t;
 +
++#define ipipe_spinlock(lock)  ((__ipipe_spinlock_t *)(lock))
 +#define ipipe_spinlock_p(lock)                                                
        \
 +      __builtin_types_compatible_p(typeof(lock), __ipipe_spinlock_t *) ||     
\
 +      __builtin_types_compatible_p(typeof(lock), __ipipe_spinlock_t [])
 +
++#define std_spinlock_raw(lock)        ((raw_spinlock_t *)(lock))
 +#define std_spinlock_raw_p(lock)                                      \
 +      __builtin_types_compatible_p(typeof(lock), raw_spinlock_t *) || \
 +      __builtin_types_compatible_p(typeof(lock), raw_spinlock_t [])
 +
++#ifdef CONFIG_PREEMPT_RT_FULL
++
++#define PICK_SPINLOCK_IRQSAVE(lock, flags)                            \
++      do {                                                            \
++              if (ipipe_spinlock_p(lock))                             \
++                      (flags) = 
__ipipe_spin_lock_irqsave(ipipe_spinlock(lock)); \
++              else if (std_spinlock_raw_p(lock))                              
\
++                      __real_raw_spin_lock_irqsave(std_spinlock_raw(lock), 
flags); \
++              else __bad_lock_type();                                 \
++      } while (0)
++
++#define PICK_SPINTRYLOCK_IRQSAVE(lock, flags)                         \
++      ({                                                              \
++              int __ret__;                                            \
++              if (ipipe_spinlock_p(lock))                             \
++                      __ret__ = 
__ipipe_spin_trylock_irqsave(ipipe_spinlock(lock), &(flags)); \
++              else if (std_spinlock_raw_p(lock))                              
\
++                      __ret__ = 
__real_raw_spin_trylock_irqsave(std_spinlock_raw(lock), flags); \
++              else __bad_lock_type();                                 \
++              __ret__;                                                \
++       })
++
++#define PICK_SPINTRYLOCK_IRQ(lock)                                    \
++      ({                                                              \
++              int __ret__;                                            \
++              if (ipipe_spinlock_p(lock))                             \
++                      __ret__ = 
__ipipe_spin_trylock_irq(ipipe_spinlock(lock)); \
++              else if (std_spinlock_raw_p(lock))                              
\
++                      __ret__ = 
__real_raw_spin_trylock_irq(std_spinlock_raw(lock)); \
++              else __bad_lock_type();                                 \
++              __ret__;                                                \
++       })
++
++#define PICK_SPINUNLOCK_IRQRESTORE(lock, flags)                               
\
++      do {                                                            \
++              if (ipipe_spinlock_p(lock))                             \
++                      __ipipe_spin_unlock_irqrestore(ipipe_spinlock(lock), 
flags); \
++              else if (std_spinlock_raw_p(lock)) {                    \
++                      __ipipe_spin_unlock_debug(flags);               \
++                      
__real_raw_spin_unlock_irqrestore(std_spinlock_raw(lock), flags); \
++              } else __bad_lock_type();                               \
++      } while (0)
++
++#define PICK_SPINOP(op, lock)                                         \
++      ({                                                              \
++              if (ipipe_spinlock_p(lock))                             \
++                      arch_spin##op(&ipipe_spinlock(lock)->arch_lock); \
++              else if (std_spinlock_raw_p(lock))                      \
++                      __real_raw_spin##op(std_spinlock_raw(lock));    \
++              else __bad_lock_type();                                 \
++              (void)0;                                                \
++      })
++
++#define PICK_SPINOP_RET(op, lock, type)                                       
\
++      ({                                                              \
++              type __ret__;                                           \
++              if (ipipe_spinlock_p(lock))                             \
++                      __ret__ = 
arch_spin##op(&ipipe_spinlock(lock)->arch_lock); \
++              else if (std_spinlock_raw_p(lock))                      \
++                      __ret__ = __real_raw_spin##op(std_spinlock_raw(lock)); \
++              else { __ret__ = -1; __bad_lock_type(); }               \
++              __ret__;                                                \
++      })
++
++#else /* !CONFIG_PREEMPT_RT_FULL */
++
++#define std_spinlock(lock)    ((spinlock_t *)(lock))
 +#define std_spinlock_p(lock)                                          \
 +      __builtin_types_compatible_p(typeof(lock), spinlock_t *) ||     \
 +      __builtin_types_compatible_p(typeof(lock), spinlock_t [])
 +
-+#define ipipe_spinlock(lock)  ((__ipipe_spinlock_t *)(lock))
-+#define std_spinlock_raw(lock)        ((raw_spinlock_t *)(lock))
-+#define std_spinlock(lock)    ((spinlock_t *)(lock))
-+
 +#define PICK_SPINLOCK_IRQSAVE(lock, flags)                            \
 +      do {                                                            \
 +              if (ipipe_spinlock_p(lock))                             \
@@ -15872,6 +16086,8 @@ index 0000000..f71d2f1
 +              __ret__;                                                \
 +      })
 +
++#endif /* !CONFIG_PREEMPT_RT_FULL */
++
 +#define arch_spin_lock_init(lock)                                     \
 +      do {                                                            \
 +              IPIPE_DEFINE_SPINLOCK(__lock__);                        \
@@ -16001,7 +16217,7 @@ index 0000000..f71d2f1
 +#define __ipipe_spin_trylock_irq(lock)                1
 +#define __ipipe_spin_trylock_irqsave(lock, x) ({ (void)(x); 1; })
 +#define __ipipe_spin_unlock_irqrestore(lock, x)       do { (void)(x); } while 
(0)
-+#define __ipipe_spin_unlock_irqbegin(lock)    do { } while (0)
++#define __ipipe_spin_unlock_irqbegin(lock)    spin_unlock(lock)
 +#define __ipipe_spin_unlock_irqcomplete(x)    do { (void)(x); } while (0)
 +#define __ipipe_spin_unlock_debug(flags)      do { } while (0)
 +
@@ -16015,10 +16231,10 @@ index 0000000..f71d2f1
 +#endif /* !__LINUX_IPIPE_LOCK_H */
 diff --git a/include/linux/ipipe_tickdev.h b/include/linux/ipipe_tickdev.h
 new file mode 100644
-index 0000000..58a4142
+index 0000000..2f065ad
 --- /dev/null
 +++ b/include/linux/ipipe_tickdev.h
-@@ -0,0 +1,145 @@
+@@ -0,0 +1,148 @@
 +/* -*- linux-c -*-
 + * include/linux/ipipe_tickdev.h
 + *
@@ -16098,6 +16314,7 @@ index 0000000..58a4142
 +                            struct clock_event_device *cdev);
 +      int (*real_set_next_event)(unsigned long evt,
 +                                 struct clock_event_device *cdev);
++      unsigned int (*refresh_freq)(void);
 +};
 +
 +#define __ipipe_hrtimer_irq __ipipe_raw_cpu_read(ipipe_percpu.hrtimer_irq)
@@ -16150,6 +16367,8 @@ index 0000000..58a4142
 +
 +unsigned ipipe_timer_ns2ticks(struct ipipe_timer *timer, unsigned ns);
 +
++void __ipipe_timer_refresh_freq(unsigned int hrclock_freq);
++
 +#else /* !CONFIG_IPIPE */
 +
 +#define ipipe_host_timer_register(clkevt) do { } while (0)
@@ -17704,7 +17923,7 @@ index 0000000..797a849
 +}
 diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
 new file mode 100644
-index 0000000..3b07d65
+index 0000000..339fb95
 --- /dev/null
 +++ b/kernel/ipipe/core.c
 @@ -0,0 +1,1916 @@
@@ -18532,7 +18751,7 @@ index 0000000..3b07d65
 +      unsigned long flags, irq = 0;
 +      int ipos;
 +
-+      spin_lock_irqsave(&__ipipe_lock, flags);
++      raw_spin_lock_irqsave(&__ipipe_lock, flags);
 +
 +      if (__ipipe_virtual_irq_map != ~0) {
 +              ipos = ffz(__ipipe_virtual_irq_map);
@@ -18540,7 +18759,7 @@ index 0000000..3b07d65
 +              irq = ipos + IPIPE_VIRQ_BASE;
 +      }
 +
-+      spin_unlock_irqrestore(&__ipipe_lock, flags);
++      raw_spin_unlock_irqrestore(&__ipipe_lock, flags);
 +
 +      return irq;
 +}
@@ -18570,7 +18789,7 @@ index 0000000..3b07d65
 +          (irq >= IPIPE_NR_XIRQS && !ipipe_virtual_irq_p(irq)))
 +              return -EINVAL;
 +
-+      spin_lock_irqsave(&__ipipe_lock, flags);
++      raw_spin_lock_irqsave(&__ipipe_lock, flags);
 +
 +      if (ipd->irqs[irq].handler) {
 +              ret = -EBUSY;
@@ -18588,7 +18807,7 @@ index 0000000..3b07d65
 +      if (irq < IPIPE_NR_ROOT_IRQS)
 +              __ipipe_enable_irqdesc(ipd, irq);
 +out:
-+      spin_unlock_irqrestore(&__ipipe_lock, flags);
++      raw_spin_unlock_irqrestore(&__ipipe_lock, flags);
 +
 +      return ret;
 +}
@@ -18603,7 +18822,7 @@ index 0000000..3b07d65
 +      ipipe_root_only();
 +#endif /* CONFIG_IPIPE_LEGACY */
 +
-+      spin_lock_irqsave(&__ipipe_lock, flags);
++      raw_spin_lock_irqsave(&__ipipe_lock, flags);
 +
 +      if (ipd->irqs[irq].handler == NULL)
 +              goto out;
@@ -18616,7 +18835,7 @@ index 0000000..3b07d65
 +      if (irq < IPIPE_NR_ROOT_IRQS)
 +              __ipipe_disable_irqdesc(ipd, irq);
 +out:
-+      spin_unlock_irqrestore(&__ipipe_lock, flags);
++      raw_spin_unlock_irqrestore(&__ipipe_lock, flags);
 +}
 +EXPORT_SYMBOL_GPL(ipipe_free_irq);
 +
@@ -19259,7 +19478,7 @@ index 0000000..3b07d65
 +       * another CPU. Enter a spinning wait until he releases the
 +       * global lock.
 +       */
-+      spin_lock(&__ipipe_cpu_barrier);
++      raw_spin_lock(&__ipipe_cpu_barrier);
 +
 +      /* Got it. Now get out. */
 +
@@ -19269,7 +19488,7 @@ index 0000000..3b07d65
 +
 +      cpumask_set_cpu(cpu, &__ipipe_cpu_pass_map);
 +
-+      spin_unlock(&__ipipe_cpu_barrier);
++      raw_spin_unlock(&__ipipe_cpu_barrier);
 +
 +      cpumask_clear_cpu(cpu, &__ipipe_cpu_sync_map);
 +}
@@ -19302,7 +19521,7 @@ index 0000000..3b07d65
 +              }
 +restart:
 +              online = *cpu_online_mask;
-+              spin_lock(&__ipipe_cpu_barrier);
++              raw_spin_lock(&__ipipe_cpu_barrier);
 +
 +              __ipipe_cpu_sync = syncfn;
 +
@@ -19328,7 +19547,7 @@ index 0000000..3b07d65
 +                       */
 +                      __ipipe_cpu_sync = NULL;
 +
-+                      spin_unlock(&__ipipe_cpu_barrier);
++                      raw_spin_unlock(&__ipipe_cpu_barrier);
 +                      /*
 +                       * Ensure all CPUs consumed the IPI to avoid
 +                       * running __ipipe_cpu_sync prematurely. This
@@ -19358,7 +19577,7 @@ index 0000000..3b07d65
 +
 +#ifdef CONFIG_SMP
 +      if (atomic_dec_and_test(&__ipipe_critical_count)) {
-+              spin_unlock(&__ipipe_cpu_barrier);
++              raw_spin_unlock(&__ipipe_cpu_barrier);
 +              while (!cpumask_empty(&__ipipe_cpu_sync_map))
 +                      cpu_relax();
 +              cpumask_clear_cpu(ipipe_processor_id(), &__ipipe_cpu_lock_map);
@@ -19626,10 +19845,10 @@ index 0000000..3b07d65
 +#endif
 diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
 new file mode 100644
-index 0000000..73f748e
+index 0000000..a9917f4
 --- /dev/null
 +++ b/kernel/ipipe/timer.c
-@@ -0,0 +1,497 @@
+@@ -0,0 +1,520 @@
 +/* -*- linux-c -*-
 + * linux/kernel/ipipe/timer.c
 + *
@@ -19756,7 +19975,7 @@ index 0000000..73f748e
 +      if (timer->cpumask == NULL)
 +              timer->cpumask = cpumask_of(smp_processor_id());
 +
-+      spin_lock_irqsave(&lock, flags);
++      raw_spin_lock_irqsave(&lock, flags);
 +
 +      list_for_each_entry(t, &timers, link) {
 +              if (t->rating <= timer->rating) {
@@ -19766,7 +19985,7 @@ index 0000000..73f748e
 +      }
 +      list_add_tail(&timer->link, &timers);
 +  done:
-+      spin_unlock_irqrestore(&lock, flags);
++      raw_spin_unlock_irqrestore(&lock, flags);
 +}
 +
 +static void ipipe_timer_request_sync(void)
@@ -19789,18 +20008,14 @@ index 0000000..73f748e
 +      timer->request(timer, steal);
 +}
 +
-+/* Set up a timer as per-cpu timer for ipipe */
-+static void install_pcpu_timer(unsigned cpu, unsigned hrclock_freq,
-+                            struct ipipe_timer *t) {
-+      unsigned hrtimer_freq;
++static void config_pcpu_timer(struct ipipe_timer *t, unsigned hrclock_freq)
++{
 +      unsigned long long tmp;
++      unsigned hrtimer_freq;
 +
-+      if (__ipipe_hrtimer_freq == 0)
++      if (__ipipe_hrtimer_freq != t->freq)
 +              __ipipe_hrtimer_freq = t->freq;
 +
-+      per_cpu(ipipe_percpu.hrtimer_irq, cpu) = t->irq;
-+      per_cpu(percpu_timer, cpu) = t;
-+
 +      hrtimer_freq = t->freq;
 +      if (__ipipe_hrclock_freq > UINT_MAX)
 +              hrtimer_freq /= 1000;
@@ -19813,6 +20028,15 @@ index 0000000..73f748e
 +      t->c2t_frac = tmp;
 +}
 +
++/* Set up a timer as per-cpu timer for ipipe */
++static void install_pcpu_timer(unsigned cpu, unsigned hrclock_freq,
++                            struct ipipe_timer *t)
++{
++      per_cpu(ipipe_percpu.hrtimer_irq, cpu) = t->irq;
++      per_cpu(percpu_timer, cpu) = t;
++      config_pcpu_timer(t, hrclock_freq);
++}
++
 +static void select_root_only_timer(unsigned cpu, unsigned hrclock_khz,
 +                                 const struct cpumask *mask,
 +                                 struct ipipe_timer *t) {
@@ -19866,7 +20090,7 @@ index 0000000..73f748e
 +      } else
 +              hrclock_freq = __ipipe_hrclock_freq;
 +
-+      spin_lock_irqsave(&lock, flags);
++      raw_spin_lock_irqsave(&lock, flags);
 +
 +      /* First, choose timers for the CPUs handled by ipipe */
 +      for_each_cpu(cpu, mask) {
@@ -19906,7 +20130,7 @@ index 0000000..73f748e
 +              }
 +      }
 +
-+      spin_unlock_irqrestore(&lock, flags);
++      raw_spin_unlock_irqrestore(&lock, flags);
 +
 +      flags = ipipe_critical_enter(ipipe_timer_request_sync);
 +      ipipe_timer_request_sync();
@@ -19915,7 +20139,7 @@ index 0000000..73f748e
 +      return 0;
 +
 +err_remove_all:
-+      spin_unlock_irqrestore(&lock, flags);
++      raw_spin_unlock_irqrestore(&lock, flags);
 +
 +      for_each_cpu(cpu, mask) {
 +              per_cpu(ipipe_percpu.hrtimer_irq, cpu) = -1;
@@ -20127,9 +20351,27 @@ index 0000000..73f748e
 +}
 +
 +#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
++
++int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
++                            bool force);
++
++void __ipipe_timer_refresh_freq(unsigned int hrclock_freq)
++{
++      struct ipipe_timer *t = __ipipe_raw_cpu_read(percpu_timer);
++      unsigned long flags;
++
++      if (t && t->refresh_freq) {
++              t->freq = t->refresh_freq();
++              flags = hard_local_irq_save();
++              config_pcpu_timer(t, hrclock_freq);
++              hard_local_irq_restore(flags);
++              clockevents_program_event(t->host_timer,
++                                        t->host_timer->next_event, false);
++      }
++}
 diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
 new file mode 100644
-index 0000000..da272c50
+index 0000000..1ae7bc2
 --- /dev/null
 +++ b/kernel/ipipe/tracer.c
 @@ -0,0 +1,1468 @@
@@ -20194,7 +20436,7 @@ index 0000000..da272c50
 +#define IPIPE_TFLG_CURRDOM_SHIFT    10         /* bits 10..11: current domain 
*/
 +#define IPIPE_TFLG_CURRDOM_MASK           0x0C00
 +#define IPIPE_TFLG_DOMSTATE_SHIFT   12         /* bits 12..15: domain 
stalled? */
-+#define IPIPE_TFLG_DOMSTATE_BITS    3
++#define IPIPE_TFLG_DOMSTATE_BITS    1
 +
 +#define IPIPE_TFLG_DOMAIN_STALLED(point, n) \
 +      (point->flags & (1 << (n + IPIPE_TFLG_DOMSTATE_SHIFT)))
@@ -20337,7 +20579,7 @@ index 0000000..da272c50
 +      if (length > per_cpu(trace_path, cpu)[per_cpu(max_path, cpu)].length) {
 +              /* we need protection here against other cpus trying
 +                 to start a proc dump */
-+              spin_lock(&global_path_lock);
++              raw_spin_lock(&global_path_lock);
 +
 +              /* active path holds new worst case */
 +              tp->length = length;
@@ -20346,7 +20588,7 @@ index 0000000..da272c50
 +              /* find next unused trace path */
 +              active = __ipipe_get_free_trace_path(active, cpu);
 +
-+              spin_unlock(&global_path_lock);
++              raw_spin_unlock(&global_path_lock);
 +
 +              tp = &per_cpu(trace_path, cpu)[active];
 +
@@ -20369,7 +20611,7 @@ index 0000000..da272c50
 +
 +      /* we need protection here against other cpus trying
 +       * to set their frozen path or to start a proc dump */
-+      spin_lock(&global_path_lock);
++      raw_spin_lock(&global_path_lock);
 +
 +      per_cpu(frozen_path, cpu) = active;
 +
@@ -20383,7 +20625,7 @@ index 0000000..da272c50
 +                      tp->end = -1;
 +      }
 +
-+      spin_unlock(&global_path_lock);
++      raw_spin_unlock(&global_path_lock);
 +
 +      tp = &per_cpu(trace_path, cpu)[active];
 +
@@ -20538,7 +20780,7 @@ index 0000000..da272c50
 +      int cpu;
 +      struct ipipe_trace_path *tp;
 +
-+      spin_lock_irqsave(&global_path_lock, flags);
++      raw_spin_lock_irqsave(&global_path_lock, flags);
 +
 +      cpu = ipipe_processor_id();
 + restart:
@@ -21467,7 +21709,7 @@ index 0000000..da272c50
 +
 +static struct ftrace_ops ipipe_trace_ops = {
 +      .func = ipipe_trace_function,
-+      .flags = FTRACE_OPS_FL_RECURSION_SAFE,
++      .flags = FTRACE_OPS_FL_IPIPE_EXCLUSIVE,
 +};
 +
 +static ssize_t __ipipe_wr_enable(struct file *file, const char __user *buffer,
@@ -22354,7 +22596,7 @@ index 2329daa..79cfe9b 100644
        if (pm_wakeup_pending()) {
                error = -EAGAIN;
 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
-index 3c1aca0..90b1189 100644
+index 3c1aca0..ae6b3d5 100644
 --- a/kernel/printk/printk.c
 +++ b/kernel/printk/printk.c
 @@ -62,6 +62,9 @@ int console_printk[4] = {
@@ -22470,7 +22712,7 @@ index 3c1aca0..90b1189 100644
 +      goto start;
 +
 +      do {
-+              spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
++              raw_spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
 + start:
 +              lmax = __ipipe_printk_fill;
 +              while (out < lmax) {
@@ -22479,13 +22721,13 @@ index 3c1aca0..90b1189 100644
 +                      p += len;
 +                      out += len;
 +              }
-+              spin_lock_irqsave(&__ipipe_printk_lock, flags);
++              raw_spin_lock_irqsave(&__ipipe_printk_lock, flags);
 +      }
 +      while (__ipipe_printk_fill != lmax);
 +
 +      __ipipe_printk_fill = 0;
 +
-+      spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
++      raw_spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
 +}
 +
  /**
@@ -22523,7 +22765,7 @@ index 3c1aca0..90b1189 100644
 +              goto out;
 +      }
 +
-+      spin_lock_irqsave(&__ipipe_printk_lock, flags);
++      raw_spin_lock_irqsave(&__ipipe_printk_lock, flags);
 +
 +      oldcount = __ipipe_printk_fill;
 +      fbytes = __LOG_BUF_LEN - oldcount;
@@ -22534,7 +22776,7 @@ index 3c1aca0..90b1189 100644
 +      } else
 +              r = 0;
 +
-+      spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
++      raw_spin_unlock_irqrestore(&__ipipe_printk_lock, flags);
 +
 +      if (oldcount == 0)
 +              ipipe_raise_irq(__ipipe_printk_virq);
@@ -23183,7 +23425,7 @@ index 3b9a48a..edd9470 100644
        help
          This option will modify all the calls to function tracing
 diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
-index eb11011..5fa6c0a 100644
+index eb11011..d0957bd 100644
 --- a/kernel/trace/ftrace.c
 +++ b/kernel/trace/ftrace.c
 @@ -32,6 +32,7 @@
@@ -23194,7 +23436,33 @@ index eb11011..5fa6c0a 100644
  
  #include <trace/events/sched.h>
  
-@@ -2518,6 +2519,9 @@ void __weak arch_ftrace_update_code(int command)
+@@ -262,8 +263,17 @@ static ftrace_func_t ftrace_ops_get_list_func(struct 
ftrace_ops *ops)
+ 
+ static void update_ftrace_function(void)
+ {
++      struct ftrace_ops *ops;
+       ftrace_func_t func;
+ 
++      for (ops = ftrace_ops_list;
++           ops != &ftrace_list_end; ops = ops->next)
++              if (ops->flags & FTRACE_OPS_FL_IPIPE_EXCLUSIVE) {
++                      set_function_trace_op = ops;
++                      func = ops->func;
++                      goto set_pointers;
++              }
++
+       /*
+        * Prepare the ftrace_ops that the arch callback will use.
+        * If there's only one ftrace_ops registered, the ftrace_ops_list
+@@ -291,6 +301,7 @@ static void update_ftrace_function(void)
+ 
+       update_function_graph_func();
+ 
++  set_pointers:
+       /* If there's no change, then do nothing more here */
+       if (ftrace_trace_function == func)
+               return;
+@@ -2518,6 +2529,9 @@ void __weak arch_ftrace_update_code(int command)
  
  static void ftrace_run_update_code(int command)
  {
@@ -23204,7 +23472,7 @@ index eb11011..5fa6c0a 100644
        int ret;
  
        ret = ftrace_arch_code_modify_prepare();
-@@ -2531,7 +2535,13 @@ static void ftrace_run_update_code(int command)
+@@ -2531,7 +2545,13 @@ static void ftrace_run_update_code(int command)
         * is safe. The stop_machine() is the safest, but also
         * produces the most overhead.
         */
@@ -23218,7 +23486,7 @@ index eb11011..5fa6c0a 100644
  
        ret = ftrace_arch_code_modify_post_process();
        FTRACE_WARN_ON(ret);
-@@ -4877,10 +4887,10 @@ static int ftrace_process_locs(struct module *mod,
+@@ -4877,10 +4897,10 @@ static int ftrace_process_locs(struct module *mod,
         * reason to cause large interrupt latencies while we do it.
         */
        if (!mod)
@@ -23231,7 +23499,7 @@ index eb11011..5fa6c0a 100644
        ret = 0;
   out:
        mutex_unlock(&ftrace_lock);
-@@ -4979,9 +4989,11 @@ void __init ftrace_init(void)
+@@ -4979,9 +4999,11 @@ void __init ftrace_init(void)
        unsigned long count, flags;
        int ret;
  
@@ -23245,7 +23513,7 @@ index eb11011..5fa6c0a 100644
        if (ret)
                goto failed;
  
-@@ -5174,7 +5186,16 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long 
parent_ip,
+@@ -5174,7 +5196,16 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long 
parent_ip,
                }
        } while_for_each_ftrace_op(op);
  out:
@@ -23605,24 +23873,22 @@ index 86c8911..373a30b 100644
        return err;
  }
 diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
-index 1afec32..5803111 100644
+index 1afec32..f7c1a2a 100644
 --- a/lib/smp_processor_id.c
 +++ b/lib/smp_processor_id.c
-@@ -12,10 +12,13 @@ notrace static unsigned int 
check_preemption_disabled(const char *what1,
+@@ -12,6 +12,12 @@ notrace static unsigned int check_preemption_disabled(const 
char *what1,
  {
        int this_cpu = raw_smp_processor_id();
  
++      if (hard_irqs_disabled())
++              goto out;
++
 +      if (!ipipe_root_p)
 +              goto out;
 +
        if (likely(preempt_count()))
                goto out;
  
--      if (irqs_disabled())
-+      if (irqs_disabled() || hard_irqs_disabled())
-               goto out;
- 
-       /*
 diff --git a/mm/memory.c b/mm/memory.c
 index 2a9e098..46ec4cd 100644
 --- a/mm/memory.c
@@ -23830,7 +24096,7 @@ index 2a9e098..46ec4cd 100644
  
  static struct kmem_cache *page_ptl_cachep;
 diff --git a/mm/mlock.c b/mm/mlock.c
-index 3d3ee6c..ed47c08 100644
+index 3d3ee6ca..ed47c08 100644
 --- a/mm/mlock.c
 +++ b/mm/mlock.c
 @@ -756,3 +756,28 @@ void user_shm_unlock(size_t size, struct user_struct 
*user)
@@ -23965,3 +24231,16 @@ index 2faaa29..ef00f26 100644
        return nr;
  }
  
+diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
+index 96c2e42..2e6e3cf 100644
+--- a/sound/soc/intel/atom/sst/sst.c
++++ b/sound/soc/intel/atom/sst/sst.c
+@@ -369,7 +369,7 @@ static inline void sst_restore_shim64(struct intel_sst_drv 
*ctx,
+        */
+       spin_lock_irqsave(&ctx->ipc_spin_lock, irq_flags);
+       sst_shim_write64(shim, SST_IMRX, shim_regs->imrx),
+-      sst_shim_write64(shim, SST_CSR, shim_regs->csr),
++      sst_shim_write64(shim, SST_CSR, shim_regs->csr);
+       spin_unlock_irqrestore(&ctx->ipc_spin_lock, irq_flags);
+ }
+ 


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

Reply via email to