[PATCHv4] irqchip: arm-gic: take gic_lock when updating irq type
From: Aniruddha Banerjee <anirudd...@nvidia.com> The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Cc: sta...@vger.kernel.org Signed-off-by: Aniruddha Banerjee <anirudd...@nvidia.com> --- Change from V1: * Moved the spinlock from irq-gic to irq-gic common, so that the fix is valid for GIC v1/v2/v3. Change from V2: * Fixup the Signed-off-by line. Change from V3: * Change raw_spin_lock to raw_spin_lock_irqsave and spin_unlock to raw_spin_unlock_irqrestore to protect against a potential deadlock when an interrupt handler changes the trigger type of any interrupt. drivers/irqchip/irq-gic-common.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..1c2ca8d51a70 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -52,11 +54,13 @@ int gic_configure_irq(unsigned int irq, unsigned int type, u32 confoff = (irq / 16) * 4; u32 val, oldval; int ret = 0; + unsigned long flags; /* * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock_irqsave(_controller_lock, flags); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +68,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock_irqrestore(_controller_lock, flags); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +89,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock_irqrestore(_controller_lock, flags); if (sync_access) sync_access(); -- 2.16.2
[PATCHv4] irqchip: arm-gic: take gic_lock when updating irq type
From: Aniruddha Banerjee The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Cc: sta...@vger.kernel.org Signed-off-by: Aniruddha Banerjee --- Change from V1: * Moved the spinlock from irq-gic to irq-gic common, so that the fix is valid for GIC v1/v2/v3. Change from V2: * Fixup the Signed-off-by line. Change from V3: * Change raw_spin_lock to raw_spin_lock_irqsave and spin_unlock to raw_spin_unlock_irqrestore to protect against a potential deadlock when an interrupt handler changes the trigger type of any interrupt. drivers/irqchip/irq-gic-common.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..1c2ca8d51a70 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -52,11 +54,13 @@ int gic_configure_irq(unsigned int irq, unsigned int type, u32 confoff = (irq / 16) * 4; u32 val, oldval; int ret = 0; + unsigned long flags; /* * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock_irqsave(_controller_lock, flags); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +68,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock_irqrestore(_controller_lock, flags); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +89,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock_irqrestore(_controller_lock, flags); if (sync_access) sync_access(); -- 2.16.2
[PATCHv3] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Signed-off-by: Aniruddha Banerjee <anirudd...@nvidia.com> --- Changes from V1: * Moved the spinlock from irq-gic to irq-gic common, so that the fix is valid for GIC v1/v2/v3. Change from V2: * Fixup the Signed-off-by line. drivers/irqchip/irq-gic-common.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..73dd39959e6e 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -57,6 +59,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock(_controller_lock); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +67,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock(_controller_lock); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +88,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock(_controller_lock); if (sync_access) sync_access(); -- 2.16.2
[PATCHv3] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Signed-off-by: Aniruddha Banerjee --- Changes from V1: * Moved the spinlock from irq-gic to irq-gic common, so that the fix is valid for GIC v1/v2/v3. Change from V2: * Fixup the Signed-off-by line. drivers/irqchip/irq-gic-common.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..73dd39959e6e 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -57,6 +59,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock(_controller_lock); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +67,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock(_controller_lock); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +88,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock(_controller_lock); if (sync_access) sync_access(); -- 2.16.2
[PATCHv2] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Signed-off-by: Aniruddha Banerjee <aniruddha.n...@gmail.com> --- drivers/irqchip/irq-gic-common.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..73dd39959e6e 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -57,6 +59,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock(_controller_lock); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +67,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock(_controller_lock); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +88,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock(_controller_lock); if (sync_access) sync_access(); -- 2.16.2
[PATCHv2] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Signed-off-by: Aniruddha Banerjee --- drivers/irqchip/irq-gic-common.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9ae71804b5dd..73dd39959e6e 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,8 @@ #include "irq-gic-common.h" +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + static const struct gic_kvm_info *gic_kvm_info; const struct gic_kvm_info *gic_get_kvm_info(void) @@ -57,6 +59,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, * Read current configuration register, and insert the config * for "irq", depending on "type". */ + raw_spin_lock(_controller_lock); val = oldval = readl_relaxed(base + GIC_DIST_CONFIG + confoff); if (type & IRQ_TYPE_LEVEL_MASK) val &= ~confmask; @@ -64,8 +67,10 @@ int gic_configure_irq(unsigned int irq, unsigned int type, val |= confmask; /* If the current configuration is the same, then we are done */ - if (val == oldval) + if (val == oldval) { + raw_spin_unlock(_controller_lock); return 0; + } /* * Write back the new configuration, and possibly re-enable @@ -83,6 +88,7 @@ int gic_configure_irq(unsigned int irq, unsigned int type, pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16); } + raw_spin_unlock(_controller_lock); if (sync_access) sync_access(); -- 2.16.2
[RFC PATCH] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the irq-chip driver should handle the locking of the irq-chip registers. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the irq_controller lock when the irq_type is updated. This patch is only for GICv2; however, I have noticed a similar implementation in GICv3. This patch is sent as an RFC in case I am missing anything. Signed-off-by: Aniruddha Banerjee <anirudd...@nvidia.com> --- drivers/irqchip/irq-gic.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4c797b43614d..61380f5a2254 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -67,6 +67,8 @@ static void gic_check_cpu_features(void) #define gic_check_cpu_features() do { } while(0) #endif +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + union gic_base { void __iomem *common_base; void __percpu * __iomem *percpu_base; @@ -529,6 +531,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) { void __iomem *base = gic_dist_base(d); unsigned int gicirq = gic_irq(d); + int ret; /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) @@ -539,7 +542,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - return gic_configure_irq(gicirq, type, base, NULL); + raw_spin_lock(_controller_lock); + ret = gic_configure_irq(gicirq, type, base, NULL); + raw_spin_unlock(_controller_lock); + + return ret; } static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) -- 2.15.1
[RFC PATCH] irqchip: arm-gic: take gic_lock when updating irq type
The kernel documentation states that the irq-chip driver should handle the locking of the irq-chip registers. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the irq_controller lock when the irq_type is updated. This patch is only for GICv2; however, I have noticed a similar implementation in GICv3. This patch is sent as an RFC in case I am missing anything. Signed-off-by: Aniruddha Banerjee --- drivers/irqchip/irq-gic.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4c797b43614d..61380f5a2254 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -67,6 +67,8 @@ static void gic_check_cpu_features(void) #define gic_check_cpu_features() do { } while(0) #endif +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + union gic_base { void __iomem *common_base; void __percpu * __iomem *percpu_base; @@ -529,6 +531,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) { void __iomem *base = gic_dist_base(d); unsigned int gicirq = gic_irq(d); + int ret; /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) @@ -539,7 +542,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - return gic_configure_irq(gicirq, type, base, NULL); + raw_spin_lock(_controller_lock); + ret = gic_configure_irq(gicirq, type, base, NULL); + raw_spin_unlock(_controller_lock); + + return ret; } static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) -- 2.15.1
[PATCH 1/1] arm64: tegra: fix PPI interrupt flag
The interrupt flag for PPI should not be set to any value, since the register is read-only. Fix the flags for the PPI interrupts to IRQ_TYPE_NONE, so that there is no write to the read-only register. Signed-off-by: Aniruddha Banerjee <anirudd...@nvidia.com> --- arch/arm64/boot/dts/nvidia/tegra132.dtsi | 8 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 8 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 8 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 3f3a46a4bd01..219fb3c6a273 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -1093,13 +1093,13 @@ timer { compatible = "arm,armv7-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 62fa85ae0271..e602299f7694 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -390,13 +390,13 @@ timer { compatible = "arm,armv8-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 2f832df29da8..6f3060b40a40 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1214,13 +1214,13 @@ timer { compatible = "arm,armv8-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; -- 2.11.0
[PATCH 1/1] arm64: tegra: fix PPI interrupt flag
The interrupt flag for PPI should not be set to any value, since the register is read-only. Fix the flags for the PPI interrupts to IRQ_TYPE_NONE, so that there is no write to the read-only register. Signed-off-by: Aniruddha Banerjee --- arch/arm64/boot/dts/nvidia/tegra132.dtsi | 8 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 8 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 8 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 3f3a46a4bd01..219fb3c6a273 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -1093,13 +1093,13 @@ timer { compatible = "arm,armv7-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 62fa85ae0271..e602299f7694 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -390,13 +390,13 @@ timer { compatible = "arm,armv8-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; }; diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 2f832df29da8..6f3060b40a40 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1214,13 +1214,13 @@ timer { compatible = "arm,armv8-timer"; interrupts = , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, , + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>, ; + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_NONE)>; interrupt-parent = <>; }; -- 2.11.0
RE: [PATCH 1/1] irq: add IRQF_TRIGGER_MASK on PPI by default
> On 31/03/17 , Marc Zyngier wrote: > On 31/03/17 09:01, Thomas Gleixner wrote: > > On Thu, 30 Mar 2017, Aniruddha Banerjee wrote: > > > >> add IRQF_TRIGGER_MASK on PPI by default so that the PPIs are not > >> configured as edge-triggered, which may be wrong for certain GIC > >> implementations such as the GIC-400 > > > > The above is just useless blurb. > > > > I can't figure out at all WHY a generic interface has anything to do > > with edge trigger configuration. > > > > I assume this is (Nvidia) GIC specific nonsense, so why are you > > inflicting this on every caller of this interface unconditionally w/o > > explaining what the impact of this change might be and why it does not > > cause havoc for any existing caller? > > > > This is function is implemented in kernel/irq/ not in foo/gic/ so you > > better come up with some coherent explanation. > > Indeed. I'm not aware of anything wrong so far with GIC400, so this is most > likely > referring to an integration issue. > > Furthermore, PPI triggers are usually not configurable on GIC400. My bet is > that this is > only a DT issue, but in the absence of any coherent justification, it is hard > to make an > educated guess... That was an awesome guess and we were in fact doing something very wrong in the DT. In the GIC-400 implementation, the PPI triggers are read-only. I was trying to configure the PPI as edge-triggered, and the writes were dropped in the process. A big thank you to Jon Hunter and Marc for pointing this out. Regards, Aniruddha.
RE: [PATCH 1/1] irq: add IRQF_TRIGGER_MASK on PPI by default
> On 31/03/17 , Marc Zyngier wrote: > On 31/03/17 09:01, Thomas Gleixner wrote: > > On Thu, 30 Mar 2017, Aniruddha Banerjee wrote: > > > >> add IRQF_TRIGGER_MASK on PPI by default so that the PPIs are not > >> configured as edge-triggered, which may be wrong for certain GIC > >> implementations such as the GIC-400 > > > > The above is just useless blurb. > > > > I can't figure out at all WHY a generic interface has anything to do > > with edge trigger configuration. > > > > I assume this is (Nvidia) GIC specific nonsense, so why are you > > inflicting this on every caller of this interface unconditionally w/o > > explaining what the impact of this change might be and why it does not > > cause havoc for any existing caller? > > > > This is function is implemented in kernel/irq/ not in foo/gic/ so you > > better come up with some coherent explanation. > > Indeed. I'm not aware of anything wrong so far with GIC400, so this is most > likely > referring to an integration issue. > > Furthermore, PPI triggers are usually not configurable on GIC400. My bet is > that this is > only a DT issue, but in the absence of any coherent justification, it is hard > to make an > educated guess... That was an awesome guess and we were in fact doing something very wrong in the DT. In the GIC-400 implementation, the PPI triggers are read-only. I was trying to configure the PPI as edge-triggered, and the writes were dropped in the process. A big thank you to Jon Hunter and Marc for pointing this out. Regards, Aniruddha.
[PATCH 1/1] irq: add IRQF_TRIGGER_MASK on PPI by default
add IRQF_TRIGGER_MASK on PPI by default so that the PPIs are not configured as edge-triggered, which may be wrong for certain GIC implementations such as the GIC-400 Signed-off-by: Aniruddha Banerjee <anirudd...@nvidia.com> --- kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 6b669593e7eb..9b2983cf9fd3 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1982,7 +1982,7 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler, return -ENOMEM; action->handler = handler; - action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND; + action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND | IRQF_TRIGGER_MASK; action->name = devname; action->percpu_dev_id = dev_id; -- 2.11.0
[PATCH 1/1] irq: add IRQF_TRIGGER_MASK on PPI by default
add IRQF_TRIGGER_MASK on PPI by default so that the PPIs are not configured as edge-triggered, which may be wrong for certain GIC implementations such as the GIC-400 Signed-off-by: Aniruddha Banerjee --- kernel/irq/manage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 6b669593e7eb..9b2983cf9fd3 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1982,7 +1982,7 @@ int request_percpu_irq(unsigned int irq, irq_handler_t handler, return -ENOMEM; action->handler = handler; - action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND; + action->flags = IRQF_PERCPU | IRQF_NO_SUSPEND | IRQF_TRIGGER_MASK; action->name = devname; action->percpu_dev_id = dev_id; -- 2.11.0
[RFC] hung_task: task white-listing for hung tasks
Hello, In the current hung_task framework, there is no way to white-list tasks for which a higher hang time out might be acceptable and expected even: Usecase: I want to keep a low hung_task timeout to catch more tasks which are hung-up. However, certain tasks (like sync, which flushes to a slow eMMC) may have a higher timeout. Problem: There is no way to implement the aforementioned usecase without increasing the hang task timeout, which will reduce the effictiveness of the hung_task framework. Solution: 1. Introduce a white-list of tasks that have a much higher timeout. 2. Create a simple sysfs interface with which it might be possible to dynamically add/remove any task in the white-list. Please let me know what you think about the problem and the proposed solution? Regards, Aniruddha
[RFC] hung_task: task white-listing for hung tasks
Hello, In the current hung_task framework, there is no way to white-list tasks for which a higher hang time out might be acceptable and expected even: Usecase: I want to keep a low hung_task timeout to catch more tasks which are hung-up. However, certain tasks (like sync, which flushes to a slow eMMC) may have a higher timeout. Problem: There is no way to implement the aforementioned usecase without increasing the hang task timeout, which will reduce the effictiveness of the hung_task framework. Solution: 1. Introduce a white-list of tasks that have a much higher timeout. 2. Create a simple sysfs interface with which it might be possible to dynamically add/remove any task in the white-list. Please let me know what you think about the problem and the proposed solution? Regards, Aniruddha