* Re: [PATCH 5/8] powerpc/5200: Don't specify IRQF_SHARED in PSC UART driver
From: Wolfram Sang @ 2009-01-29 21:24 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090121205529.31232.64801.stgit@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 1490 bytes --]
On Wed, Jan 21, 2009 at 01:55:29PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> The MPC5200 PSC device is wired up to a dedicated interrupt line
> which is never shared. This patch removes the IRQF_SHARED flag
> from the request_irq() call which eliminates the "IRQF_DISABLED
> is not guaranteed on shared IRQs" warning message from the console
> output.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
What do I give here? Acked-by? Reviewed? Tested? :D I'll make a guess:
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
> ---
>
> drivers/serial/mpc52xx_uart.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
>
> diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
> index d73d7da..7f72f8c 100644
> --- a/drivers/serial/mpc52xx_uart.c
> +++ b/drivers/serial/mpc52xx_uart.c
> @@ -522,7 +522,7 @@ mpc52xx_uart_startup(struct uart_port *port)
>
> /* Request IRQ */
> ret = request_irq(port->irq, mpc52xx_uart_int,
> - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
> + IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
> "mpc52xx_psc_uart", port);
> if (ret)
> return ret;
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
--
Dipl.-Ing. Wolfram Sang | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH 6/8] powerpc/5200: Remove pr_debug() from hot paths in irq driver
From: Wolfram Sang @ 2009-01-29 21:29 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090121205534.31232.68165.stgit@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 4067 bytes --]
On Wed, Jan 21, 2009 at 01:55:35PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> pr_debug() calls in the 'hot' *_mask(), *_unmask(), *_ack() and
> get_irq() makes adding #define DEBUG pretty much useless. Remove
> these calls because they completely swamp the output.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Yup!
Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
> ---
>
> arch/powerpc/platforms/52xx/mpc52xx_pic.c | 23 -----------------------
> 1 files changed, 0 insertions(+), 23 deletions(-)
>
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> index 0a093f0..c0a9559 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> @@ -163,8 +163,6 @@ static void mpc52xx_extirq_mask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_clrbit(&intr->ctrl, 11 - l2irq);
> }
>
> @@ -176,8 +174,6 @@ static void mpc52xx_extirq_unmask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_setbit(&intr->ctrl, 11 - l2irq);
> }
>
> @@ -189,8 +185,6 @@ static void mpc52xx_extirq_ack(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_setbit(&intr->ctrl, 27-l2irq);
> }
>
> @@ -255,8 +249,6 @@ static void mpc52xx_main_mask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_setbit(&intr->main_mask, 16 - l2irq);
> }
>
> @@ -268,8 +260,6 @@ static void mpc52xx_main_unmask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_clrbit(&intr->main_mask, 16 - l2irq);
> }
>
> @@ -291,8 +281,6 @@ static void mpc52xx_periph_mask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_setbit(&intr->per_mask, 31 - l2irq);
> }
>
> @@ -304,8 +292,6 @@ static void mpc52xx_periph_unmask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_clrbit(&intr->per_mask, 31 - l2irq);
> }
>
> @@ -327,8 +313,6 @@ static void mpc52xx_sdma_mask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_setbit(&sdma->IntMask, l2irq);
> }
>
> @@ -340,8 +324,6 @@ static void mpc52xx_sdma_unmask(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> io_be_clrbit(&sdma->IntMask, l2irq);
> }
>
> @@ -353,8 +335,6 @@ static void mpc52xx_sdma_ack(unsigned int virq)
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
> -
> out_be32(&sdma->IntPend, 1 << l2irq);
> }
>
> @@ -613,8 +593,5 @@ unsigned int mpc52xx_get_irq(void)
> }
> }
>
> - pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
> - irq_linear_revmap(mpc52xx_irqhost, irq));
> -
> return irq_linear_revmap(mpc52xx_irqhost, irq);
> }
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
--
Dipl.-Ing. Wolfram Sang | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH 7/8] powerpc/5200: Refactor mpc5200 interrupt controller driver
From: Wolfram Sang @ 2009-01-29 21:33 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090121205540.31232.77034.stgit@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 9275 bytes --]
On Wed, Jan 21, 2009 at 01:55:41PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Rework the mpc5200-pic driver to simplify it and fix up the setting
> of desc->status when set_type is called for internal IRQs (so they
> are reported as level, not edge). The simplification is due to
> splitting off the handling of external IRQs into a separate block
> so they don't need to be handled as exceptions in the normal
> CRIT, MAIN and PERP paths.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> CC: Wolfram Sang <w.sang@pengutronix.de>
Can't say much about this one as I have never dealt with the PIC
directly so far. Yet, my phyCORE-MPC5200B-tiny behaves normal, so
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
> ---
>
> arch/powerpc/platforms/52xx/mpc52xx_pic.c | 145 ++++++++++++-----------------
> 1 files changed, 58 insertions(+), 87 deletions(-)
>
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> index c0a9559..277c9c5 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
> @@ -190,10 +190,10 @@ static void mpc52xx_extirq_ack(unsigned int virq)
>
> static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
> {
> - struct irq_desc *desc = get_irq_desc(virq);
> u32 ctrl_reg, type;
> int irq;
> int l2irq;
> + void *handler = handle_level_irq;
>
> irq = irq_map[virq].hwirq;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
> @@ -201,32 +201,21 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
> pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
>
> switch (flow_type) {
> - case IRQF_TRIGGER_HIGH:
> - type = 0;
> - break;
> - case IRQF_TRIGGER_RISING:
> - type = 1;
> - break;
> - case IRQF_TRIGGER_FALLING:
> - type = 2;
> - break;
> - case IRQF_TRIGGER_LOW:
> - type = 3;
> - break;
> + case IRQF_TRIGGER_HIGH: type = 0; break;
> + case IRQF_TRIGGER_RISING: type = 1; handler = handle_edge_irq; break;
> + case IRQF_TRIGGER_FALLING: type = 2; handler = handle_edge_irq; break;
> + case IRQF_TRIGGER_LOW: type = 3; break;
> default:
> type = 0;
> }
>
> - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
> - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
> - if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
> - desc->status |= IRQ_LEVEL;
> -
> ctrl_reg = in_be32(&intr->ctrl);
> ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
> ctrl_reg |= (type << (22 - (l2irq * 2)));
> out_be32(&intr->ctrl, ctrl_reg);
>
> + __set_irq_handler_unlocked(virq, handler);
> +
> return 0;
> }
>
> @@ -241,6 +230,11 @@ static struct irq_chip mpc52xx_extirq_irqchip = {
> /*
> * Main interrupt irq_chip
> */
> +static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
> +{
> + return 0; /* Do nothing so that the sense mask will get updated */
> +}
> +
> static void mpc52xx_main_mask(unsigned int virq)
> {
> int irq;
> @@ -268,6 +262,7 @@ static struct irq_chip mpc52xx_main_irqchip = {
> .mask = mpc52xx_main_mask,
> .mask_ack = mpc52xx_main_mask,
> .unmask = mpc52xx_main_unmask,
> + .set_type = mpc52xx_null_set_type,
> };
>
> /*
> @@ -300,6 +295,7 @@ static struct irq_chip mpc52xx_periph_irqchip = {
> .mask = mpc52xx_periph_mask,
> .mask_ack = mpc52xx_periph_mask,
> .unmask = mpc52xx_periph_unmask,
> + .set_type = mpc52xx_null_set_type,
> };
>
> /*
> @@ -343,9 +339,19 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
> .mask = mpc52xx_sdma_mask,
> .unmask = mpc52xx_sdma_unmask,
> .ack = mpc52xx_sdma_ack,
> + .set_type = mpc52xx_null_set_type,
> };
>
> /**
> + * mpc52xx_is_extirq - Returns true if hwirq number is for an external IRQ
> + */
> +static int mpc52xx_is_extirq(int l1, int l2)
> +{
> + return ((l1 == 0) && (l2 == 0)) ||
> + ((l1 == 1) && (l2 >= 1) && (l2 <= 3));
> +}
> +
> +/**
> * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
> */
> static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
> @@ -363,38 +369,23 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
>
> intrvect_l1 = (int)intspec[0];
> intrvect_l2 = (int)intspec[1];
> - intrvect_type = (int)intspec[2];
> + intrvect_type = (int)intspec[2] & 0x3;
>
> intrvect_linux = (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) &
> MPC52xx_IRQ_L1_MASK;
> intrvect_linux |= intrvect_l2 & MPC52xx_IRQ_L2_MASK;
>
> - pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
> - intrvect_l2);
> -
> *out_hwirq = intrvect_linux;
> - *out_flags = mpc52xx_map_senses[intrvect_type];
> + *out_flags = IRQ_TYPE_LEVEL_LOW;
> + if (mpc52xx_is_extirq(intrvect_l1, intrvect_l2))
> + *out_flags = mpc52xx_map_senses[intrvect_type];
>
> + pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
> + intrvect_l2);
> return 0;
> }
>
> /**
> - * mpc52xx_irqx_gettype - determine the IRQ sense type (level/edge)
> - *
> - * Only external IRQs need this.
> - */
> -static int mpc52xx_irqx_gettype(int irq)
> -{
> - int type;
> - u32 ctrl_reg;
> -
> - ctrl_reg = in_be32(&intr->ctrl);
> - type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
> -
> - return mpc52xx_map_senses[type];
> -}
> -
> -/**
> * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
> */
> static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
> @@ -402,68 +393,46 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
> {
> int l1irq;
> int l2irq;
> - struct irq_chip *good_irqchip;
> + struct irq_chip *irqchip;
> void *good_handle;
> int type;
> + u32 reg;
>
> l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
> l2irq = irq & MPC52xx_IRQ_L2_MASK;
>
> /*
> - * Most of ours IRQs will be level low
> - * Only external IRQs on some platform may be others
> + * External IRQs are handled differently by the hardware so they are
> + * handled by a dedicated irq_chip structure.
> */
> - type = IRQ_TYPE_LEVEL_LOW;
> + if (mpc52xx_is_extirq(l1irq, l2irq)) {
> + reg = in_be32(&intr->ctrl);
> + type = mpc52xx_map_senses[(reg >> (22 - l2irq * 2)) & 0x3];
> + if ((type == IRQ_TYPE_EDGE_FALLING) ||
> + (type == IRQ_TYPE_EDGE_RISING))
> + good_handle = handle_edge_irq;
> + else
> + good_handle = handle_level_irq;
> +
> + set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, good_handle);
> + pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n",
> + __func__, l2irq, virq, (int)irq, type);
> + return 0;
> + }
>
> + /* It is an internal SOC irq. Choose the correct irq_chip */
> switch (l1irq) {
> - case MPC52xx_IRQ_L1_CRIT:
> - pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
> -
> - BUG_ON(l2irq != 0);
> -
> - type = mpc52xx_irqx_gettype(l2irq);
> - good_irqchip = &mpc52xx_extirq_irqchip;
> - break;
> -
> - case MPC52xx_IRQ_L1_MAIN:
> - pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
> -
> - if ((l2irq >= 1) && (l2irq <= 3)) {
> - type = mpc52xx_irqx_gettype(l2irq);
> - good_irqchip = &mpc52xx_extirq_irqchip;
> - } else {
> - good_irqchip = &mpc52xx_main_irqchip;
> - }
> - break;
> -
> - case MPC52xx_IRQ_L1_PERP:
> - pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
> - good_irqchip = &mpc52xx_periph_irqchip;
> - break;
> -
> - case MPC52xx_IRQ_L1_SDMA:
> - pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
> - good_irqchip = &mpc52xx_sdma_irqchip;
> - break;
> -
> + case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
> + case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
> + case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
> default:
> - pr_err("%s: invalid virq requested (0x%x)\n", __func__, virq);
> + pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
> + __func__, virq, l1irq, l2irq);
> return -EINVAL;
> }
>
> - switch (type) {
> - case IRQ_TYPE_EDGE_FALLING:
> - case IRQ_TYPE_EDGE_RISING:
> - good_handle = handle_edge_irq;
> - break;
> - default:
> - good_handle = handle_level_irq;
> - }
> -
> - set_irq_chip_and_handler(virq, good_irqchip, good_handle);
> -
> - pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
> - (int)irq, type);
> + set_irq_chip_and_handler(virq, irqchip, handle_level_irq);
> + pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq);
>
> return 0;
> }
> @@ -502,6 +471,8 @@ void __init mpc52xx_init_irq(void)
> panic(__FILE__ ": find_and_map failed on 'mpc5200-bestcomm'. "
> "Check node !");
>
> + pr_debug("MPC5200 IRQ controller mapped to 0x%p\n", intr);
> +
> /* Disable all interrupt sources. */
> out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
> out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
>
--
Dipl.-Ing. Wolfram Sang | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* 2.6.28-rt on PowerPC
From: Anton Vorontsov @ 2009-01-29 21:34 UTC (permalink / raw)
To: Steven Rostedt; +Cc: linuxppc-dev, linux-kernel, linux-rt-users
Hi Steven,
I know 2.6.28-rt isn't yet ready, but I could not resist to try
it anyway. ;-)
Here are few issues and ways to solve them:
Currently the -rt tree doesn't link for arch/powerpc:
LD .tmp_vmlinux1
arch/powerpc/kernel/built-in.o: In function `show_interrupts':
(.text+0x27bc): undefined reference to `__call_bad_lock_func'
arch/powerpc/kernel/built-in.o: In function `show_interrupts':
(.text+0x28b0): undefined reference to `__call_bad_lock_func'
make: *** [.tmp_vmlinux1] Error 1
This can be trivially fixed:
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 838857f..cc7dd12 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -183,7 +183,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (i < NR_IRQS) {
desc = get_irq_desc(i);
- acquire_lock_irqsave(&desc->lock, flags);
+ spin_lock_irqsave(&desc->lock, flags);
action = desc->action;
if (!action || !action->handler)
goto skip;
@@ -204,7 +204,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
skip:
- release_lock_irqrestore(&desc->lock, flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
} else if (i == NR_IRQS) {
#if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
if (tau_initialized){
--
While booting, this bug appears:
BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
in_atomic(): 1 [00010001], irqs_disabled(): 1, pid: 1, name: swapper
Call Trace:
[cf82f9a0] [c0008be8] show_stack+0x4c/0x16c (unreliable)
[cf82f9e0] [c001c184] __might_sleep+0xd8/0xf8
[cf82f9f0] [c02b7758] rt_spin_lock+0x30/0x78
[cf82fa00] [c001853c] ipic_mask_irq+0x3c/0xb0
[cf82fa20] [c0054064] handle_level_irq+0x40/0x178
[cf82fa40] [c00068ec] do_IRQ+0x68/0xe0
[cf82fa50] [c0012924] ret_from_except+0x0/0x14
--- Exception: 501 at internal_add_timer+0x4/0xe0
This is trivially solved by converting arch/powerpc/sysdev/ipic.c
back to spinlocks (ipic_lock).
Assuming that converting-back is automatic, there are few other
chained interrupt controllers you might want to convert-back:
arch/powerpc/sysdev/i8259.c (i8259_lock)
arch/powerpc/sysdev/mpic.c (mpic_lock)
arch/powerpc/sysdev/qe_lib/qe_ic.c (qe_ic_lock)
After this, kernel boots up to the userspace, but then bugs in the
middle (note: this is NFS boot, network activity etc.)...
INIT: version 2.86 booting
Starting the hotplug events dispatcher: udevd.
Synthesizing the initial hotplug events...done.
Waiting for /dev to be fully populated...done.
Activating swap...done.
Remounting root filesystem...done.
Checking all file systems: fsck
fsck 1.40 (29-Jun-2007)
Checking SELinux contexts: selinux-basics.
Starting network interfaces: done.
Starting portmap daemon....
Cleaning: /tmp /var/lock /var/run done.
Setting pseudo-terminal access permissions...done.
Updating /etc/motd...done.
INIT: Entering runlevel: 3
Starting irqbalance.
Starting system log daemon: syslogd
BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
in_atomic(): 1 [00000100], irqs_disabled(): 0, pid: 7, name: sirq-net-rx/0
Call Trace:
[cf84bc20] [c0008be8] show_stack+0x4c/0x16c (unreliable)
[cf84bc60] [c001c194] __might_sleep+0xd8/0xf8
[cf84bc70] [c02b7768] rt_spin_lock+0x30/0x78
[cf84bc80] [c00800e0] kmem_cache_alloc+0x50/0x17c
[cf84bcb0] [c02568a4] ip_append_data+0x974/0x978
[cf84bd30] [c027aa0c] icmp_push_reply+0x54/0x128
[cf84bd50] [c027b59c] icmp_send+0x284/0x380
[cf84be40] [c0277328] __udp4_lib_rcv+0x3d4/0x5a0
[cf84bea0] [c0253208] ip_local_deliver_finish+0x74/0x128
[cf84bec0] [c0252fd0] ip_rcv_finish+0x148/0x30c
[cf84bf00] [c0236774] netif_receive_skb+0x21c/0x2e8
[cf84bf30] [c0238ecc] process_backlog+0x98/0x138
[cf84bf60] [c0238b24] net_rx_action+0xd4/0x198
[cf84bf90] [c002989c] ksoftirqd+0x108/0x23c
[cf84bfd0] [c003c918] kthread+0x48/0x84
[cf84bff0] [c00120b0] kernel_thread+0x4c/0x68
BUG: scheduling while atomic: sirq-net-rx/0/7/0x10000101, CPU#0
Modules linked in:
Call Trace:
[cf84bee0] [c0008be8] show_stack+0x4c/0x16c (unreliable)
[cf84bf20] [c001e418] __schedule_bug+0x6c/0x80
[cf84bf30] [c02b5fdc] schedule+0x2e8/0x31c
[cf84bf70] [c001e460] __cond_resched+0x34/0x60
[cf84bf80] [c02b6348] _cond_resched+0x50/0x58
[cf84bf90] [c00298b8] ksoftirqd+0x124/0x23c
[cf84bfd0] [c003c918] kthread+0x48/0x84
[cf84bff0] [c00120b0] kernel_thread+0x4c/0x68
And now this looks like not PowerPC specific... Converting mm/slab.c
back to spinlocks results in another, but similar bug in anther mm
routine:
BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
in_atomic(): 1 [00000001], irqs_disabled(): 0, pid: 1003, name: net.agent
Call Trace:
[cf057c40] [c0008be8] show_stack+0x4c/0x16c (unreliable)
[cf057c80] [c001c194] __might_sleep+0xd8/0xf8
[cf057c90] [c02b7768] rt_spin_lock+0x30/0x78
[cf057ca0] [c005d0ec] free_hot_cold_page+0xf8/0x35c
[cf057cc0] [c007f0b0] kmem_freepages+0xd8/0x134
[cf057cd0] [c007f620] slab_destroy+0x38/0xe0
[cf057cf0] [c007f814] free_block+0x14c/0x158
[cf057d30] [c007f174] cache_flusharray+0x68/0x150
[cf057d60] [c007f4fc] kmem_cache_free+0x110/0x140
[cf057d80] [c006eb04] remove_vma+0x78/0xc0
[cf057d90] [c006eccc] exit_mmap+0x180/0x208
[cf057dc0] [c00210c8] mmput+0x64/0x114
[cf057de0] [c008b580] exec_mmap+0xd8/0x1b4
[cf057e10] [c008b7c4] flush_old_exec+0x50/0x1d0
[cf057e40] [c00c2fac] load_elf_binary+0x2b0/0x96c
[cf057eb0] [c008ad6c] search_binary_handler+0xf4/0x31c
[cf057ef0] [c008c220] do_execve+0x1b4/0x1ec
[cf057f20] [c000983c] sys_execve+0x50/0x7c
[cf057f40] [c001228c] ret_from_syscall+0x0/0x38
--- Exception: c01 at 0xfeab104
LR = 0x10024540
..proves that "convert-back" trick isn't panacea. ;-) So, before
I'll dig into this.. is this known issue? Any ideas of proper
fixing?
FWIW, following options enabled:
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_RT=y
CONFIG_PREEMPT=y
CONFIG_PREEMPT_RCU=y
CONFIG_PREEMPT_SOFTIRQS=y
CONFIG_PREEMPT_HARDIRQS=y
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_SCHED_DEBUG=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_SLAB=y
CONFIG_SLABINFO=y
# CONFIG_HIGHMEM is not set
Thanks,
p.s. Btw, having the convert-back script in scripts/ would be
useful. Could not find it anywhere.
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply related
* Re: [PATCH 1/3] powerpc: bare minimum checkpoint/restart implementation
From: Nathan Lynch @ 2009-01-29 21:40 UTC (permalink / raw)
To: Oren Laadan; +Cc: containers, linuxppc-dev
In-Reply-To: <49814FA2.9060108@cs.columbia.edu>
Hey Oren, thanks for taking a look.
Oren Laadan wrote:
>
> Nathan Lynch wrote:
> >
> > What doesn't work:
> > * restarting a 32-bit task from a 64-bit task and vice versa
>
> Is there a test to bail if we attempt to checkpoint such tasks ?
No, but I'll add one if it looks too hard to fix for the next round.
> > +struct cr_hdr_cpu {
> > + struct pt_regs pt_regs;
>
> It has been suggested (as done in x86/32 code) not to use 'struct pt_regs'
> because it "can (and has) changed on x86" and because "it only container
> the registers that the kernel trashes, not all usermode registers".
>
> https://lists.linux-foundation.org/pipermail/containers/2008-August/012355.html
Yeah, I considered that discussion, but the situation is different for
powerpc (someone on linuxppc-dev smack me if I'm wrong here :)
pt_regs is part of the ABI, and it encompasses all user mode registers
except for floating point, which are handled separately.
> > + /* relevant fields from thread_struct */
> > + double fpr[32][TS_FPRWIDTH];
>
> Can TS_FPRWIDTH change between sub-archs or kernel versions ? If so, it
> needs to be stated explicitly.
>
> > + unsigned int fpscr;
> > + int fpexc_mode;
> > + /* unsigned int align_ctl; this is never updated? */
> > + unsigned long dabr;
>
> Are these fields always guarantee to compile to the same number of bytes
> regardless of 32/64 bit choice of compiler (or sub-arch?) ?
>
> In the x86(32/64) architecture we use types with explicit size such as
> __u32 and the like to ensure that it always compiled to the same
> size.
Yeah, I'll have to fix these up.
> > +static void cr_hdr_init(struct cr_hdr *hdr, __s16 type, __s16 len, __u32 parent)
> > +{
> > + hdr->type = type;
> > + hdr->len = len;
> > + hdr->parent = parent;
> > +}
> > +
>
> This function is rather generic and useful to non-arch-dependent and other
> architectures code. Perhaps put in a separate patch ?
Alright. By the way, why are cr_hdr->type and cr_hdr->len signed
types?
> > +int cr_write_cpu(struct cr_ctx *ctx, struct task_struct *t)
> > +{
> > + struct cr_hdr_cpu *cpu_hdr;
> > + struct pt_regs *pt_regs;
> > + struct cr_hdr cr_hdr;
> > + u32 parent;
> > + int ret;
> > +
> > + cpu_hdr = cr_hbuf_get(ctx, sizeof(*cpu_hdr));
> > + if (!cpu_hdr)
> > + return -ENOMEM;
> > +
> > + parent = task_pid_vnr(t);
> > +
> > + cr_hdr_init(&cr_hdr, CR_HDR_CPU, sizeof(*cpu_hdr), parent);
> > +
> > + /* pt_regs: GPRs, MSR, etc */
> > + pt_regs = task_pt_regs(t);
> > + cpu_hdr->pt_regs = *pt_regs;
> > +
> > + /* FP state */
> > + memcpy(cpu_hdr->fpr, t->thread.fpr, sizeof(cpu_hdr->fpr));
>
> As note above, is sizeof(cpu_hdr->fpr) the same on all chips ?
It can differ depending on kernel configuration.
> > +/* restart APIs */
> > +
>
> The restart APIs belong in a separate file: arch/powerpc/mm/restart.c
Explain why, please? This isn't a lot of code, and it seems likely
that checkpoint and restart paths will share data structures and tend
to be modified together over time.
> > + pr_debug("%s: unexpected thread_hdr contents: 0x%lx\n",
> > + __func__, (unsigned long)thread_hdr->unimplemented);
>
> Given the macro for 'pr_fmt' in include/linux/checkpoint.h, the use of
> __func__ is redunant.
It seems to me that defining your own pr_fmt in a "public" header like
that is inappropriate, or at least unconventional. Any file that
happens to include linux/checkpoint.h will have any prior definitions
of pr_fmt overridden, no?
> > + regs = task_pt_regs(current);
> > + *regs = cpu_hdr->pt_regs;
> > +
> > + regs->msr = sanitize_msr(regs->msr);
> > +
> > + /* FP state */
> > + memcpy(current->thread.fpr, cpu_hdr->fpr, sizeof(current->thread.fpr));
> > + current->thread.fpscr.val = cpu_hdr->fpscr;
> > + current->thread.fpexc_mode = cpu_hdr->fpexc_mode;
> > +
> > + /* debug registers */
> > + current->thread.dabr = cpu_hdr->dabr;
>
> I'm unfamiliar with powerpc; is it necessary to sanitize any of the registers
> here ? For instance, can the user cause harm with specially crafted values
> of some registers ?
I had this in mind with the treatment of MSR, but I'll check on the
others, thanks.
> > +int cr_read_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int rparent)
> > +{
> > + struct cr_hdr_mm_context *mm_hdr;
> > + int ret;
> > +
> > + mm_hdr = cr_hbuf_get(ctx, sizeof(*mm_hdr));
> > + if (!mm_hdr)
> > + return -ENOMEM;
> > +
> > + ret = cr_read_obj_type(ctx, mm_hdr, sizeof(*mm_hdr),
> > + CR_HDR_MM_CONTEXT);
> > + if (ret != rparent)
> > + goto out;
>
> Seems like 'ret' isn't set to an error value if the 'goto' executes.
It returns whatever error value cr_read_obj_type() returns. Hrm. I
guess if the image is garbage, cr_read_obj_type can potentially return
a non-error value that still isn't the desired value, is that right?
^ permalink raw reply
* Re: [PATCH] powerpc/5200: Bugfix for PCI mapping of memory and IMMR
From: Wolfram Sang @ 2009-01-29 21:49 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20090127043315.26160.43312.stgit@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 3825 bytes --]
On Mon, Jan 26, 2009 at 09:34:36PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> This patch ensures that memory gets properly mapped into the PCI
> address space. Without this patch, the memory window BAR is left
> at whatever value happened to be loaded into the BAR when Linux
> was booted. Without this patch, memory could end up getting mapped
> at any of the 1G address boundaries instead of at '0' where Linux
> expects it.
>
> Similarly, this patch also ensures that the internally memory mapped
> registers (IMMR) are mapped to the correct PCI address range.
>
> Without this patch, PCI appears to work correctly until a PCI
> device is inserted which DMAs into memory.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
No regression with a phyCORE-MPC5200B-tiny. U-Boot did probably the
right thing here...
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
> ---
>
> This is a bugfix that I intend to merge into 2.6.29 and once it is
> mainlined get it added to the stable queue. If you have a 5200 system,
> please test and make sure it works for you.
>
> Thanks
> g.
>
> arch/powerpc/platforms/52xx/mpc52xx_pci.c | 24 ++++++++++--------------
> 1 files changed, 10 insertions(+), 14 deletions(-)
>
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> index c3f2c21..87ff522 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
> @@ -20,14 +20,6 @@
>
>
> /* ======================================================================== */
> -/* PCI windows config */
> -/* ======================================================================== */
> -
> -#define MPC52xx_PCI_TARGET_IO 0xf0000000
> -#define MPC52xx_PCI_TARGET_MEM 0x00000000
> -
> -
> -/* ======================================================================== */
> /* Structures mapping & Defines for PCI Unit */
> /* ======================================================================== */
>
> @@ -244,7 +236,7 @@ static struct pci_ops mpc52xx_pci_ops = {
>
> static void __init
> mpc52xx_pci_setup(struct pci_controller *hose,
> - struct mpc52xx_pci __iomem *pci_regs)
> + struct mpc52xx_pci __iomem *pci_regs, phys_addr_t pci_phys)
> {
> struct resource *res;
> u32 tmp;
> @@ -314,10 +306,14 @@ mpc52xx_pci_setup(struct pci_controller *hose,
> /* Set all the IWCR fields at once; they're in the same reg */
> out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
>
> - out_be32(&pci_regs->tbatr0,
> - MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
> - out_be32(&pci_regs->tbatr1,
> - MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
> + /* Map IMMR onto PCI bus */
> + pci_phys &= 0xfffc0000; /* bar0 has only 14 significant bits */
> + out_be32(&pci_regs->tbatr0, MPC52xx_PCI_TBATR_ENABLE | pci_phys);
> + out_be32(&pci_regs->bar0, PCI_BASE_ADDRESS_MEM_PREFETCH | pci_phys);
> +
> + /* Map memory onto PCI bus */
> + out_be32(&pci_regs->tbatr1, MPC52xx_PCI_TBATR_ENABLE);
> + out_be32(&pci_regs->bar1, PCI_BASE_ADDRESS_MEM_PREFETCH);
>
> out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD | MPC52xx_PCI_TCR_WCT8);
>
> @@ -414,7 +410,7 @@ mpc52xx_add_bridge(struct device_node *node)
>
> /* Finish setting up PCI using values obtained by
> * pci_proces_bridge_OF_ranges */
> - mpc52xx_pci_setup(hose, pci_regs);
> + mpc52xx_pci_setup(hose, pci_regs, rsrc.start);
>
> return 0;
> }
>
--
Dipl.-Ing. Wolfram Sang | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: Broken PCI on Sequoia
From: Benjamin Herrenschmidt @ 2009-01-29 22:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: Linux/PPC Development
In-Reply-To: <alpine.LRH.2.00.0901291819440.22142@vixen.sonytel.be>
On Thu, 2009-01-29 at 18:37 +0100, Geert Uytterhoeven wrote:
> Hi Ben, Josh,
.../...
> Git-reverting this commit on top of 2.6.29-rc3 makes the crash go away.
>
> Perhaps sequoia.dts (and other 44x DTS files) had to be changed, too?
Weird, maybe I have a bug when there is no ISA hole in the DT, I'll have
a look later today.
Cheers,
Ben.
^ permalink raw reply
* mpc8270 and fs_enet
From: James Black @ 2009-01-29 22:41 UTC (permalink / raw)
To: linuxppc-dev
I've got an mpc8270 running the fs_enet v1.0 driver and we are having
problems with randomly corrupted tx buffer descriptor ready bits. The
CPM never clears the bit. This is a 2.6.19.2 kernel. We have the same
kernel with the 8260_io driver (kernel is from the denx ELDK4.2)
running on the mpc8250 that works perfect.
I've been through the clock tree in u-boot and the kernel with both
processors and they are configured corrected. I've checked all the
pins and they are configured correctly. I back ported some spin_lock
tx issues from 2.6.27.xx and still it is not working on the mpc8270.
These are the tests I am failing.
nmap -sS -v <target ip>
mpc8270 Target Output
~ # fs_enet: eth0 FS_ENET ERROR(s) 0xe
fs_enet: eth0 FS_ENET ERROR(s) 0xe
fs_enet: eth0 FS_ENET ERROR(s) 0xc
fs_enet: eth0 FS_ENET ERROR(s) 0x4
fs_enet: eth0 FS_ENET ERROR(s) 0x4
fs_enet: eth0 FS_ENET ERROR(s) 0xc
fs_enet: eth0 FS_ENET ERROR(s) 0xc
fs_enet: eth0 FS_ENET ERROR(s) 0xc
fs_enet: eth0 FS_ENET ERROR(s) 0xc
fs_enet: eth0 FS_ENET ERROR(s) 0x4
fs_enet: eth0 FS_ENET ERROR(s) 0x4
Host output-------------------------------------------------------------------------
[root@localhost linux]# nmap -sS -v 172.22.250.113
Starting Nmap 4.52 ( http://insecure.org ) at 2009-01-29 14:59 MST
Initiating Ping Scan at 14:59
Scanning 172.22.250.113 [2 ports]
Completed Ping Scan at 14:59, 0.00s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 14:59
Completed Parallel DNS resolution of 1 host. at 14:59, 0.27s elapsed
Initiating SYN Stealth Scan at 14:59
Scanning 172.22.250.113 [1714 ports]
Discovered open port 23/tcp on 172.22.250.113
Discovered open port 80/tcp on 172.22.250.113
Discovered open port 21/tcp on 172.22.250.113
<eventually times out>
telnet <target ip>
ftpput -u <user name> -p <password> <host ip> <big file> <big file>
The telnet session hangs. Below is a BDI dump of the buffer
descriptors for the tx side.
Notice the BDs with a leading 0xd such as the ones at address
0x0e6e2100 and 0x0efe21d0. I can go in and clear the ready bit by hand
with the BDI and everything starts working again without a reboot. The
BDs on the rx side look text book perfect.
0e6e2100 : dc0005ea 0df8709e 1c0005ea 0df5f89e ......p.........
0e6e2110 : 5c0005ea 0e29e89e 5c0005ea 0e29609e \....)..\....)`.
0e6e2120 : 1c000358 0e29389e 5c00002a 0fa293c2 ...X.)8.\..*....
0e6e2130 : 5c00005a 0c42c202 5c00005a 0c42c802 \..Z.B..\..Z.B..
0e6e2140 : 1c00005a 0c42c602 5c00002a 0fa292c2 ...Z.B..\..*....
0e6e2150 : 5c0005ea 0df8909e 1c0005ea 0df8c09e \...............
0e6e2160 : 5c0005ea 0e29a09e 1c0005ea 0e29a89e \....).......)..
0e6e2170 : 5c0005ea 0e29989e 5c0005ea 0e29189e \....)..\....)..
0e6e2180 : 1c0005ea 0df8989e 5c0005ea 0e29789e ........\....)x.
0e6e2190 : 1c0005ea 0df8189e 5c0005ea 0df8109e ........\.......
0e6e21a0 : 1c0005ea 0d86c09e 1c0005ea 0d86c89e ................
0e6e21b0 : 5c0005ea 0e29d89e 1c0005ea 0e29d09e \....).......)..
0e6e21c0 : 5c0005ea 0e2bd89e 5c0005ea 0e2bd09e \....+..\....+..
0e6e21d0 : dc0005ea 0e29289e 5c0005ea 0df8689e .....)(.\.....h.
0e6e21e0 : 1c0005ea 0e29f09e 5c0005ea 0e29909e .....)..\....)..
0e6e21f0 : dc0005ea 0df8609e 3c0005ea 0df6109e ......`.<.......
Anyone have any experience about what could make such a difference
between the two processors?
--
Jim Black
Senior Software Engineer
Aztek Networks, Inc.
2477 55th Street, Suite 202
Boulder, CO 80301
www.azteknetworks.com
^ permalink raw reply
* Re: 2.6.28-rt on PowerPC
From: Steven Rostedt @ 2009-01-29 23:00 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev, linux-kernel, linux-rt-users
In-Reply-To: <20090129213429.GA29014@oksana.dev.rtsoft.ru>
On Fri, 2009-01-30 at 00:34 +0300, Anton Vorontsov wrote:
> Hi Steven,
>
> I know 2.6.28-rt isn't yet ready, but I could not resist to try
> it anyway. ;-)
>
> Here are few issues and ways to solve them:
>
> Currently the -rt tree doesn't link for arch/powerpc:
>
> LD .tmp_vmlinux1
> arch/powerpc/kernel/built-in.o: In function `show_interrupts':
> (.text+0x27bc): undefined reference to `__call_bad_lock_func'
> arch/powerpc/kernel/built-in.o: In function `show_interrupts':
> (.text+0x28b0): undefined reference to `__call_bad_lock_func'
> make: *** [.tmp_vmlinux1] Error 1
Thanks! I have not yet had the chance to apply any arch patches yet. I
do plan on doing so after getting the code mostly working on x86.
>
> This can be trivially fixed:
>
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 838857f..cc7dd12 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -183,7 +183,7 @@ int show_interrupts(struct seq_file *p, void *v)
>
> if (i < NR_IRQS) {
> desc = get_irq_desc(i);
> - acquire_lock_irqsave(&desc->lock, flags);
> + spin_lock_irqsave(&desc->lock, flags);
> action = desc->action;
> if (!action || !action->handler)
> goto skip;
> @@ -204,7 +204,7 @@ int show_interrupts(struct seq_file *p, void *v)
> seq_printf(p, ", %s", action->name);
> seq_putc(p, '\n');
> skip:
> - release_lock_irqrestore(&desc->lock, flags);
> + spin_unlock_irqrestore(&desc->lock, flags);
> } else if (i == NR_IRQS) {
> #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT)
> if (tau_initialized){
>
> --
>
>
>
> While booting, this bug appears:
>
> BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
> in_atomic(): 1 [00010001], irqs_disabled(): 1, pid: 1, name: swapper
> Call Trace:
> [cf82f9a0] [c0008be8] show_stack+0x4c/0x16c (unreliable)
> [cf82f9e0] [c001c184] __might_sleep+0xd8/0xf8
> [cf82f9f0] [c02b7758] rt_spin_lock+0x30/0x78
> [cf82fa00] [c001853c] ipic_mask_irq+0x3c/0xb0
> [cf82fa20] [c0054064] handle_level_irq+0x40/0x178
> [cf82fa40] [c00068ec] do_IRQ+0x68/0xe0
> [cf82fa50] [c0012924] ret_from_except+0x0/0x14
> --- Exception: 501 at internal_add_timer+0x4/0xe0
>
> This is trivially solved by converting arch/powerpc/sysdev/ipic.c
> back to spinlocks (ipic_lock).
>
> Assuming that converting-back is automatic, there are few other
> chained interrupt controllers you might want to convert-back:
>
> arch/powerpc/sysdev/i8259.c (i8259_lock)
> arch/powerpc/sysdev/mpic.c (mpic_lock)
> arch/powerpc/sysdev/qe_lib/qe_ic.c (qe_ic_lock)
Thanks! I'll add them to the file:
scripts/convert-locks-list
>
>
>
> After this, kernel boots up to the userspace, but then bugs in the
> middle (note: this is NFS boot, network activity etc.)...
>
> INIT: version 2.86 booting
> Starting the hotplug events dispatcher: udevd.
> Synthesizing the initial hotplug events...done.
> Waiting for /dev to be fully populated...done.
> Activating swap...done.
> Remounting root filesystem...done.
> Checking all file systems: fsck
> fsck 1.40 (29-Jun-2007)
> Checking SELinux contexts: selinux-basics.
> Starting network interfaces: done.
> Starting portmap daemon....
> Cleaning: /tmp /var/lock /var/run done.
> Setting pseudo-terminal access permissions...done.
> Updating /etc/motd...done.
> INIT: Entering runlevel: 3
> Starting irqbalance.
> Starting system log daemon: syslogd
> BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
> in_atomic(): 1 [00000100], irqs_disabled(): 0, pid: 7, name: sirq-net-rx/0
> Call Trace:
> [cf84bc20] [c0008be8] show_stack+0x4c/0x16c (unreliable)
> [cf84bc60] [c001c194] __might_sleep+0xd8/0xf8
> [cf84bc70] [c02b7768] rt_spin_lock+0x30/0x78
> [cf84bc80] [c00800e0] kmem_cache_alloc+0x50/0x17c
> [cf84bcb0] [c02568a4] ip_append_data+0x974/0x978
> [cf84bd30] [c027aa0c] icmp_push_reply+0x54/0x128
> [cf84bd50] [c027b59c] icmp_send+0x284/0x380
> [cf84be40] [c0277328] __udp4_lib_rcv+0x3d4/0x5a0
> [cf84bea0] [c0253208] ip_local_deliver_finish+0x74/0x128
> [cf84bec0] [c0252fd0] ip_rcv_finish+0x148/0x30c
> [cf84bf00] [c0236774] netif_receive_skb+0x21c/0x2e8
> [cf84bf30] [c0238ecc] process_backlog+0x98/0x138
> [cf84bf60] [c0238b24] net_rx_action+0xd4/0x198
> [cf84bf90] [c002989c] ksoftirqd+0x108/0x23c
> [cf84bfd0] [c003c918] kthread+0x48/0x84
> [cf84bff0] [c00120b0] kernel_thread+0x4c/0x68
> BUG: scheduling while atomic: sirq-net-rx/0/7/0x10000101, CPU#0
> Modules linked in:
> Call Trace:
> [cf84bee0] [c0008be8] show_stack+0x4c/0x16c (unreliable)
> [cf84bf20] [c001e418] __schedule_bug+0x6c/0x80
> [cf84bf30] [c02b5fdc] schedule+0x2e8/0x31c
> [cf84bf70] [c001e460] __cond_resched+0x34/0x60
> [cf84bf80] [c02b6348] _cond_resched+0x50/0x58
> [cf84bf90] [c00298b8] ksoftirqd+0x124/0x23c
> [cf84bfd0] [c003c918] kthread+0x48/0x84
> [cf84bff0] [c00120b0] kernel_thread+0x4c/0x68
Turn on CONFIG_PREEMPT_TRACE (not TRACER) and it should show the
location that left preemption disabled.
>
>
> And now this looks like not PowerPC specific... Converting mm/slab.c
> back to spinlocks results in another, but similar bug in anther mm
> routine:
Oh, mm/slab.c should not have spinlocks.
>
> BUG: sleeping function called from invalid context at kernel/rtmutex.c:683
> in_atomic(): 1 [00000001], irqs_disabled(): 0, pid: 1003, name: net.agent
> Call Trace:
> [cf057c40] [c0008be8] show_stack+0x4c/0x16c (unreliable)
> [cf057c80] [c001c194] __might_sleep+0xd8/0xf8
> [cf057c90] [c02b7768] rt_spin_lock+0x30/0x78
> [cf057ca0] [c005d0ec] free_hot_cold_page+0xf8/0x35c
> [cf057cc0] [c007f0b0] kmem_freepages+0xd8/0x134
> [cf057cd0] [c007f620] slab_destroy+0x38/0xe0
> [cf057cf0] [c007f814] free_block+0x14c/0x158
> [cf057d30] [c007f174] cache_flusharray+0x68/0x150
> [cf057d60] [c007f4fc] kmem_cache_free+0x110/0x140
> [cf057d80] [c006eb04] remove_vma+0x78/0xc0
> [cf057d90] [c006eccc] exit_mmap+0x180/0x208
> [cf057dc0] [c00210c8] mmput+0x64/0x114
> [cf057de0] [c008b580] exec_mmap+0xd8/0x1b4
> [cf057e10] [c008b7c4] flush_old_exec+0x50/0x1d0
> [cf057e40] [c00c2fac] load_elf_binary+0x2b0/0x96c
> [cf057eb0] [c008ad6c] search_binary_handler+0xf4/0x31c
> [cf057ef0] [c008c220] do_execve+0x1b4/0x1ec
> [cf057f20] [c000983c] sys_execve+0x50/0x7c
> [cf057f40] [c001228c] ret_from_syscall+0x0/0x38
> --- Exception: c01 at 0xfeab104
> LR = 0x10024540
>
> ..proves that "convert-back" trick isn't panacea. ;-) So, before
> I'll dig into this.. is this known issue? Any ideas of proper
> fixing?
>
> FWIW, following options enabled:
>
> CONFIG_NO_HZ=y
> CONFIG_HIGH_RES_TIMERS=y
> CONFIG_PREEMPT_RT=y
> CONFIG_PREEMPT=y
> CONFIG_PREEMPT_RCU=y
> CONFIG_PREEMPT_SOFTIRQS=y
> CONFIG_PREEMPT_HARDIRQS=y
> CONFIG_DEBUG_FS=y
> CONFIG_DEBUG_KERNEL=y
> CONFIG_SCHED_DEBUG=y
> CONFIG_DEBUG_RT_MUTEXES=y
> CONFIG_DEBUG_PI_LIST=y
> CONFIG_DEBUG_SPINLOCK=y
> CONFIG_DEBUG_SPINLOCK_SLEEP=y
> CONFIG_DEBUG_BUGVERBOSE=y
> CONFIG_SLAB=y
> CONFIG_SLABINFO=y
> # CONFIG_HIGHMEM is not set
>
> Thanks,
>
> p.s. Btw, having the convert-back script in scripts/ would be
> useful. Could not find it anywhere.
It is, but it is called convert-locks-list ;-)
Yeah, you can blame me for bad naming.
-- Steve
^ permalink raw reply
* Re: mpc8270 and fs_enet
From: Scott Wood @ 2009-01-29 23:05 UTC (permalink / raw)
To: James Black; +Cc: linuxppc-dev
In-Reply-To: <b77025b40901291441j7790f85ewd70ee81dc09ed55b@mail.gmail.com>
James Black wrote:
> I've got an mpc8270 running the fs_enet v1.0 driver and we are having
> problems with randomly corrupted tx buffer descriptor ready bits. The
> CPM never clears the bit. This is a 2.6.19.2 kernel. We have the same
> kernel with the 8260_io driver (kernel is from the denx ELDK4.2)
> running on the mpc8250 that works perfect.
Is it possible that some other CPM block is configured to use the same
DPRAM area that the descriptors are in?
-Scott
^ permalink raw reply
* Re: 2.6.28-rt on PowerPC
From: Frank Rowand @ 2009-01-29 23:21 UTC (permalink / raw)
To: Steven Rostedt; +Cc: linuxppc-dev, linux-kernel, linux-rt-users
In-Reply-To: <1233270043.3833.57.camel@localhost.localdomain>
Steven Rostedt wrote:
> On Fri, 2009-01-30 at 00:34 +0300, Anton Vorontsov wrote:
>> Hi Steven,
>>
>> I know 2.6.28-rt isn't yet ready, but I could not resist to try
>> it anyway. ;-)
>>
>> Here are few issues and ways to solve them:
>>
>> Currently the -rt tree doesn't link for arch/powerpc:
>>
>> LD .tmp_vmlinux1
>> arch/powerpc/kernel/built-in.o: In function `show_interrupts':
>> (.text+0x27bc): undefined reference to `__call_bad_lock_func'
>> arch/powerpc/kernel/built-in.o: In function `show_interrupts':
>> (.text+0x28b0): undefined reference to `__call_bad_lock_func'
>> make: *** [.tmp_vmlinux1] Error 1
>
> Thanks! I have not yet had the chance to apply any arch patches yet. I
> do plan on doing so after getting the code mostly working on x86.
Your email can at an opportune time for me... I was starting to try
2.6.28-rt on ARM and quickly came to the conclusion that the arch
patches weren't the focus yet. But I'm currently side-tracked with
getting my board to even boot a vanilla 2.6.28 kernel first. Do
you expect to get to the arches in the next week or two? If not,
I may head down that path for ARM myself.
Thanks!
-Frank Rowand
^ permalink raw reply
* [PATCH 1/1] powerpc: Fix partition migration hang under load
From: Brian King @ 2009-01-29 23:23 UTC (permalink / raw)
To: benh; +Cc: brking, linuxppc-dev
While testing partition migration with heavy CPU load using
shared processors, it was observed that sometimes the migration
would never complete and would appear to hang. Currently, the
migration code assumes that if H_SUCCESS is returned from the H_JOIN
then the migration is complete and the processor is waking up on
the target system. If there was an outstanding PROD to the processor
when the H_JOIN is called, however, it will return H_SUCCESS on the source
system, causing the migration to hang, or in some scenarios cause
the kernel to crash on the complete call waking the caller
of rtas_percpu_suspend_me. Fix this by calling H_JOIN multiple times
if necessary during the migration.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
---
arch/powerpc/kernel/rtas.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff -puN arch/powerpc/kernel/rtas.c~powerpc_migration_hang_fix arch/powerpc/kernel/rtas.c
--- linux-2.6/arch/powerpc/kernel/rtas.c~powerpc_migration_hang_fix 2009-01-29 17:19:58.000000000 -0600
+++ linux-2.6-bjking1/arch/powerpc/kernel/rtas.c 2009-01-29 17:19:58.000000000 -0600
@@ -46,6 +46,7 @@ EXPORT_SYMBOL(rtas);
struct rtas_suspend_me_data {
atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
int token; /* ibm,suspend-me */
int error;
struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_U
#ifdef CONFIG_PPC_PSERIES
static void rtas_percpu_suspend_me(void *info)
{
- long rc;
+ long rc = H_SUCCESS;
unsigned long msr_save;
int cpu;
struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- rc = plpar_hcall_norets(H_JOIN);
+ while (rc == H_SUCCESS && !atomic_read(&data->done))
+ rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void
smp_processor_id(), rc);
data->error = rc;
}
+
+ atomic_set(&data->done, 1);
+
/* This cpu did the suspend or got an error; in either case,
* we need to prod all other other cpus out of join state.
* Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rt
}
atomic_set(&data.working, 0);
+ atomic_set(&data.done, 0);
data.token = rtas_token("ibm,suspend-me");
data.error = 0;
data.complete = &done;
_
^ permalink raw reply
* Re: mpc8270 and fs_enet
From: James Black @ 2009-01-29 23:27 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <49823647.2010701@freescale.com>
I thought the same thing. So I verified the memory map. We did have a
conflict with the SPI stomping the FCC temp so we moved that. An
interesting note is that we drop packets from time to time on the MCC
as well due to a similar ready bit problem. The CPM never clears the
bit.
------------------------------------------------------------------
IMMR memory map
------------------------------------------------------------------
> FCC1 Parameters 0x8400 256
> FCC1 Temp buffer 0x9000 128
> SCC1 Parameters 0x8000 256
> SCC2 Parameters 0x8100 256
> SCC4 Parameters 0x8300 256
> SMC1 Parameters 0x0000 64
> SMC2 Parameters 0x0040 64
> SCC1 Buff Desc 0x0080 64
> SCC2 Buff Desc 0x00C0 64
> SCC4 Buff Desc 0x0100 64
> SPI Param Pointer 0x89FC 2
> SPI Parameters 0x9000 76
> MCC2 Global Param 0x8800 128
> MCC2 HDLC Param 0x2000 8192
> MCC2 Extra Param 0xB000 1024
On Thu, Jan 29, 2009 at 4:05 PM, Scott Wood <scottwood@freescale.com> wrote:
> James Black wrote:
>>
>> I've got an mpc8270 running the fs_enet v1.0 driver and we are having
>> problems with randomly corrupted tx buffer descriptor ready bits. The
>> CPM never clears the bit. This is a 2.6.19.2 kernel. We have the same
>> kernel with the 8260_io driver (kernel is from the denx ELDK4.2)
>> running on the mpc8250 that works perfect.
>
> Is it possible that some other CPM block is configured to use the same DPRAM
> area that the descriptors are in?
>
> -Scott
>
--
Jim Black
Senior Software Engineer
Aztek Networks, Inc.
2477 55th Street, Suite 202
Boulder, CO 80301
www.azteknetworks.com
^ permalink raw reply
* [PATCH] powerpc/5200: update device tree binding documentation
From: Grant Likely @ 2009-01-29 23:59 UTC (permalink / raw)
To: linuxppc-dev; +Cc: devicetree-discuss
From: Grant Likely <grant.likely@secretlab.ca>
This patch updates the mpc5200 binding documentation to match
actual usage conventions, to remove incorrect information, and
to remove topics which are more thoroughly described elsewhere.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
CC: devicetree-discuss@ozlabs.org
CC: Wolfram Sang <w.sang@pengutronix.de>
---
Documentation/powerpc/dts-bindings/fsl/mpc5200.txt | 180 +++++++++++++
.../powerpc/mpc52xx-device-tree-bindings.txt | 277 --------------------
2 files changed, 180 insertions(+), 277 deletions(-)
create mode 100644 Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
delete mode 100644 Documentation/powerpc/mpc52xx-device-tree-bindings.txt
diff --git a/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt b/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
new file mode 100644
index 0000000..b8b09d3
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/mpc5200.txt
@@ -0,0 +1,180 @@
+MPC5200 Device Tree Bindings
+----------------------------
+
+(c) 2006-2009 Secret Lab Technologies Ltd
+Grant Likely <grant.likely@secretlab.ca>
+
+Naming conventions
+------------------
+For mpc5200 on-chip devices, the format for each compatible value is
+<chip>-<device>[-<mode>]. The OS should be able to match a device driver
+to the device based solely on the compatible value. If two drivers
+match on the compatible list; the 'most compatible' driver should be
+selected.
+
+The split between the MPC5200 and the MPC5200B leaves a bit of a
+conundrum. How should the compatible property be set up to provide
+maximum compatibility information; but still accurately describe the
+chip? For the MPC5200; the answer is easy. Most of the SoC devices
+originally appeared on the MPC5200. Since they didn't exist anywhere
+else; the 5200 compatible properties will contain only one item;
+"fsl,mpc5200-<device>".
+
+The 5200B is almost the same as the 5200, but not quite. It fixes
+silicon bugs and it adds a small number of enhancements. Most of the
+devices either provide exactly the same interface as on the 5200. A few
+devices have extra functions but still have a backwards compatible mode.
+To express this information as completely as possible, 5200B device trees
+should have two items in the compatible list:
+ compatible = "fsl,mpc5200b-<device>","fsl,mpc5200-<device>";
+
+It is *strongly* recommended that 5200B device trees follow this convention
+(instead of only listing the base mpc5200 item).
+
+ie. ethernet on mpc5200: compatible = "fsl,mpc5200-fec";
+ ethernet on mpc5200b: compatible = "fsl,mpc5200b-fec", "fsl,mpc5200-fec";
+
+Modal devices, like PSCs, also append the configured function to the
+end of the compatible field. ie. A PSC in i2s mode would specify
+"fsl,mpc5200-psc-i2s", not "fsl,mpc5200-i2s". This convention is chosen to
+avoid naming conflicts with non-psc devices providing the same
+function. For example, "fsl,mpc5200-spi" and "fsl,mpc5200-psc-spi" describe
+the mpc5200 simple spi device and a PSC spi mode respectively.
+
+At the time of writing, exact chip may be either 'fsl,mpc5200' or
+'fsl,mpc5200b'.
+
+The soc node
+------------
+This node describes the on chip SOC peripherals. Every mpc5200 based
+board will have this node, and as such there is a common naming
+convention for SOC devices.
+
+Required properties:
+name description
+---- -----------
+ranges Memory range of the internal memory mapped registers.
+ Should be <0 [baseaddr] 0xc000>
+reg Should be <[baseaddr] 0x100>
+compatible mpc5200: "fsl,mpc5200-immr"
+ mpc5200b: "fsl,mpc5200b-immr"
+system-frequency 'fsystem' frequency in Hz; XLB, IPB, USB and PCI
+ clocks are derived from the fsystem clock.
+bus-frequency IPB bus frequency in HZ. Clock rate
+ used by most of the soc devices.
+
+soc child nodes
+---------------
+Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
+
+Note: The tables below show the value for the mpc5200. A mpc5200b device
+tree should use the "fsl,mpc5200b-<device>","fsl,mpc5200-<device>" form.
+
+Required soc5200 child nodes:
+name compatible Description
+---- ---------- -----------
+cdm@<addr> fsl,mpc5200-cdm Clock Distribution
+interrupt-controller@<addr> fsl,mpc5200-pic need an interrupt
+ controller to boot
+bestcomm@<addr> fsl,mpc5200-bestcomm Bestcomm DMA controller
+
+Recommended soc5200 child nodes; populate as needed for your board
+name compatible Description
+---- ---------- -----------
+timer@<addr> fsl,mpc5200-gpt General purpose timers
+gpio@<addr> fsl,mpc5200-gpio MPC5200 simple gpio controller
+gpio@<addr> fsl,mpc5200-gpio-wkup MPC5200 wakeup gpio controller
+rtc@<addr> fsl,mpc5200-rtc Real time clock
+mscan@<addr> fsl,mpc5200-mscan CAN bus controller
+pci@<addr> fsl,mpc5200-pci PCI bridge
+serial@<addr> fsl,mpc5200-psc-uart PSC in serial mode
+i2s@<addr> fsl,mpc5200-psc-i2s PSC in i2s mode
+ac97@<addr> fsl,mpc5200-psc-ac97 PSC in ac97 mode
+spi@<addr> fsl,mpc5200-psc-spi PSC in spi mode
+irda@<addr> fsl,mpc5200-psc-irda PSC in IrDA mode
+spi@<addr> fsl,mpc5200-spi MPC5200 spi device
+ethernet@<addr> fsl,mpc5200-fec MPC5200 ethernet device
+ata@<addr> fsl,mpc5200-ata IDE ATA interface
+i2c@<addr> fsl,mpc5200-i2c I2C controller
+usb@<addr> fsl,mpc5200-ohci,ohci-be USB controller
+xlb@<addr> fsl,mpc5200-xlb XLB arbitrator
+
+fsl,mpc5200-gpt nodes
+---------------------
+On the mpc5200 and 5200b, GPT0 has a watchdog timer function. If the board
+design supports the internal wdt, then the device node for GPT0 should
+include the empty property 'fsl,has-wdt'.
+
+An mpc5200-gpt can be used as a single line GPIO controller. To do so,
+add the following properties to the gpt node:
+ gpio-controller;
+ #gpio-cells = <2>;
+When referencing the GPIO line from another node, the first cell must always
+be zero and the second cell represents the gpio flags and described in the
+gpio device tree binding.
+
+An mpc5200-gpt can be used as a single line edge sensitive interrupt
+controller. To do so, add the following properties to the gpt node:
+ interrupt-controller;
+ #interrupt-cells = <1>;
+When referencing the IRQ line from another node, the cell represents the
+sense mode; 1 for edge rising, 2 for edge falling.
+
+fsl,mpc5200-psc nodes
+---------------------
+The PSCs should include a cell-index which is the index of the PSC in
+hardware. cell-index is used to determine which shared SoC registers to
+use when setting up PSC clocking. cell-index number starts at '0'. ie:
+ PSC1 has 'cell-index = <0>'
+ PSC4 has 'cell-index = <3>'
+
+PSC in i2s mode: The mpc5200 and mpc5200b PSCs are not compatible when in
+i2s mode. An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the
+compatible field.
+
+
+fsl,mpc5200-gpio and fsl,mpc5200-gpio-wkup nodes
+------------------------------------------------
+Each GPIO controller node should have the empty property gpio-controller and
+#gpio-cells set to 2. First cell is the GPIO number which is interpreted
+according to the bit numbers in the GPIO control registers. The second cell
+is for flags which is currently unused.
+
+fsl,mpc5200-fec nodes
+---------------------
+The FEC node can specify one of the following properties to configure
+the MII link:
+- fsl,7-wire-mode - An empty property that specifies the link uses 7-wire
+ mode instead of MII
+- current-speed - Specifies that the MII should be configured for a fixed
+ speed. This property should contain two cells. The
+ first cell specifies the speed in Mbps and the second
+ should be '0' for half duplex and '1' for full duplex
+- phy-handle - Contains a phandle to an Ethernet PHY.
+
+Interrupt controller (fsl,mpc5200-pic) node
+-------------------------------------------
+The mpc5200 pic binding splits hardware IRQ numbers into two levels. The
+split reflects the layout of the PIC hardware itself, which groups
+interrupts into one of three groups; CRIT, MAIN or PERP. Also, the
+Bestcomm dma engine has it's own set of interrupt sources which are
+cascaded off of peripheral interrupt 0, which the driver interprets as a
+fourth group, SDMA.
+
+The interrupts property for device nodes using the mpc5200 pic consists
+of three cells; <L1 L2 level>
+
+ L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
+ L2 := interrupt number; directly mapped from the value in the
+ "ICTL PerStat, MainStat, CritStat Encoded Register"
+ level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
+
+For external IRQs, use the following interrupt property values (how to
+specify external interrupts is a frequently asked question):
+External interrupts:
+ external irq0: interrupts = <0 0 n>;
+ external irq1: interrupts = <1 1 n>;
+ external irq2: interrupts = <1 2 n>;
+ external irq3: interrupts = <1 3 n>;
+'n' is sense (0: level high, 1: edge rising, 2: edge falling 3: level low)
+
diff --git a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
deleted file mode 100644
index 6f12f1c..0000000
--- a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
+++ /dev/null
@@ -1,277 +0,0 @@
-MPC5200 Device Tree Bindings
-----------------------------
-
-(c) 2006-2007 Secret Lab Technologies Ltd
-Grant Likely <grant.likely at secretlab.ca>
-
-********** DRAFT ***********
-* WARNING: Do not depend on the stability of these bindings just yet.
-* The MPC5200 device tree conventions are still in flux
-* Keep an eye on the linuxppc-dev mailing list for more details
-********** DRAFT ***********
-
-I - Introduction
-================
-Boards supported by the arch/powerpc architecture require device tree be
-passed by the boot loader to the kernel at boot time. The device tree
-describes what devices are present on the board and how they are
-connected. The device tree can either be passed as a binary blob (as
-described in Documentation/powerpc/booting-without-of.txt), or passed
-by Open Firmware (IEEE 1275) compatible firmware using an OF compatible
-client interface API.
-
-This document specifies the requirements on the device-tree for mpc5200
-based boards. These requirements are above and beyond the details
-specified in either the Open Firmware spec or booting-without-of.txt
-
-All new mpc5200-based boards are expected to match this document. In
-cases where this document is not sufficient to support a new board port,
-this document should be updated as part of adding the new board support.
-
-II - Philosophy
-===============
-The core of this document is naming convention. The whole point of
-defining this convention is to reduce or eliminate the number of
-special cases required to support a 5200 board. If all 5200 boards
-follow the same convention, then generic 5200 support code will work
-rather than coding special cases for each new board.
-
-This section tries to capture the thought process behind why the naming
-convention is what it is.
-
-1. names
----------
-There is strong convention/requirements already established for children
-of the root node. 'cpus' describes the processor cores, 'memory'
-describes memory, and 'chosen' provides boot configuration. Other nodes
-are added to describe devices attached to the processor local bus.
-
-Following convention already established with other system-on-chip
-processors, 5200 device trees should use the name 'soc5200' for the
-parent node of on chip devices, and the root node should be its parent.
-
-Child nodes are typically named after the configured function. ie.
-the FEC node is named 'ethernet', and a PSC in uart mode is named 'serial'.
-
-2. device_type property
------------------------
-similar to the node name convention above; the device_type reflects the
-configured function of a device. ie. 'serial' for a uart and 'spi' for
-an spi controller. However, while node names *should* reflect the
-configured function, device_type *must* match the configured function
-exactly.
-
-3. compatible property
-----------------------
-Since device_type isn't enough to match devices to drivers, there also
-needs to be a naming convention for the compatible property. Compatible
-is an list of device descriptions sorted from specific to generic. For
-the mpc5200, the required format for each compatible value is
-<chip>-<device>[-<mode>]. The OS should be able to match a device driver
-to the device based solely on the compatible value. If two drivers
-match on the compatible list; the 'most compatible' driver should be
-selected.
-
-The split between the MPC5200 and the MPC5200B leaves a bit of a
-conundrum. How should the compatible property be set up to provide
-maximum compatibility information; but still accurately describe the
-chip? For the MPC5200; the answer is easy. Most of the SoC devices
-originally appeared on the MPC5200. Since they didn't exist anywhere
-else; the 5200 compatible properties will contain only one item;
-"mpc5200-<device>".
-
-The 5200B is almost the same as the 5200, but not quite. It fixes
-silicon bugs and it adds a small number of enhancements. Most of the
-devices either provide exactly the same interface as on the 5200. A few
-devices have extra functions but still have a backwards compatible mode.
-To express this information as completely as possible, 5200B device trees
-should have two items in the compatible list;
-"mpc5200b-<device>\0mpc5200-<device>". It is *strongly* recommended
-that 5200B device trees follow this convention (instead of only listing
-the base mpc5200 item).
-
-If another chip appear on the market with one of the mpc5200 SoC
-devices, then the compatible list should include mpc5200-<device>.
-
-ie. ethernet on mpc5200: compatible = "mpc5200-ethernet"
- ethernet on mpc5200b: compatible = "mpc5200b-ethernet\0mpc5200-ethernet"
-
-Modal devices, like PSCs, also append the configured function to the
-end of the compatible field. ie. A PSC in i2s mode would specify
-"mpc5200-psc-i2s", not "mpc5200-i2s". This convention is chosen to
-avoid naming conflicts with non-psc devices providing the same
-function. For example, "mpc5200-spi" and "mpc5200-psc-spi" describe
-the mpc5200 simple spi device and a PSC spi mode respectively.
-
-If the soc device is more generic and present on other SOCs, the
-compatible property can specify the more generic device type also.
-
-ie. mscan: compatible = "mpc5200-mscan\0fsl,mscan";
-
-At the time of writing, exact chip may be either 'mpc5200' or
-'mpc5200b'.
-
-Device drivers should always try to match as generically as possible.
-
-III - Structure
-===============
-The device tree for an mpc5200 board follows the structure defined in
-booting-without-of.txt with the following additional notes:
-
-0) the root node
-----------------
-Typical root description node; see booting-without-of
-
-1) The cpus node
-----------------
-The cpus node follows the basic layout described in booting-without-of.
-The bus-frequency property holds the XLB bus frequency
-The clock-frequency property holds the core frequency
-
-2) The memory node
-------------------
-Typical memory description node; see booting-without-of.
-
-3) The soc5200 node
--------------------
-This node describes the on chip SOC peripherals. Every mpc5200 based
-board will have this node, and as such there is a common naming
-convention for SOC devices.
-
-Required properties:
-name type description
----- ---- -----------
-device_type string must be "soc"
-ranges int should be <0 baseaddr baseaddr+10000>
-reg int must be <baseaddr 10000>
-compatible string mpc5200: "mpc5200-soc"
- mpc5200b: "mpc5200b-soc\0mpc5200-soc"
-system-frequency int Fsystem frequency; source of all
- other clocks.
-bus-frequency int IPB bus frequency in HZ. Clock rate
- used by most of the soc devices.
-#interrupt-cells int must be <3>.
-
-Recommended properties:
-name type description
----- ---- -----------
-model string Exact model of the chip;
- ie: model="fsl,mpc5200"
-revision string Silicon revision of chip
- ie: revision="M08A"
-
-The 'model' and 'revision' properties are *strongly* recommended. Having
-them presence acts as a bit of a safety net for working around as yet
-undiscovered bugs on one version of silicon. For example, device drivers
-can use the model and revision properties to decide if a bug fix should
-be turned on.
-
-4) soc5200 child nodes
-----------------------
-Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
-
-Note: The tables below show the value for the mpc5200. A mpc5200b device
-tree should use the "mpc5200b-<device>\0mpc5200-<device> form.
-
-Required soc5200 child nodes:
-name device_type compatible Description
----- ----------- ---------- -----------
-cdm@<addr> cdm mpc5200-cmd Clock Distribution
-pic@<addr> interrupt-controller mpc5200-pic need an interrupt
- controller to boot
-bestcomm@<addr> dma-controller mpc5200-bestcomm 5200 pic also requires
- the bestcomm device
-
-Recommended soc5200 child nodes; populate as needed for your board
-name device_type compatible Description
----- ----------- ---------- -----------
-gpt@<addr> gpt fsl,mpc5200-gpt General purpose timers
-gpt@<addr> gpt fsl,mpc5200-gpt-gpio General purpose
- timers in GPIO mode
-gpio@<addr> fsl,mpc5200-gpio MPC5200 simple gpio
- controller
-gpio@<addr> fsl,mpc5200-gpio-wkup MPC5200 wakeup gpio
- controller
-rtc@<addr> rtc mpc5200-rtc Real time clock
-mscan@<addr> mscan mpc5200-mscan CAN bus controller
-pci@<addr> pci mpc5200-pci PCI bridge
-serial@<addr> serial mpc5200-psc-uart PSC in serial mode
-i2s@<addr> sound mpc5200-psc-i2s PSC in i2s mode
-ac97@<addr> sound mpc5200-psc-ac97 PSC in ac97 mode
-spi@<addr> spi mpc5200-psc-spi PSC in spi mode
-irda@<addr> irda mpc5200-psc-irda PSC in IrDA mode
-spi@<addr> spi mpc5200-spi MPC5200 spi device
-ethernet@<addr> network mpc5200-fec MPC5200 ethernet device
-ata@<addr> ata mpc5200-ata IDE ATA interface
-i2c@<addr> i2c mpc5200-i2c I2C controller
-usb@<addr> usb-ohci-be mpc5200-ohci,ohci-be USB controller
-xlb@<addr> xlb mpc5200-xlb XLB arbitrator
-
-Important child node properties
-name type description
----- ---- -----------
-cell-index int When multiple devices are present, is the
- index of the device in the hardware (ie. There
- are 6 PSC on the 5200 numbered PSC1 to PSC6)
- PSC1 has 'cell-index = <0>'
- PSC4 has 'cell-index = <3>'
-
-5) General Purpose Timer nodes (child of soc5200 node)
-On the mpc5200 and 5200b, GPT0 has a watchdog timer function. If the board
-design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'fsl,has-wdt'.
-
-6) PSC nodes (child of soc5200 node)
-PSC nodes can define the optional 'port-number' property to force assignment
-order of serial ports. For example, PSC5 might be physically connected to
-the port labeled 'COM1' and PSC1 wired to 'COM1'. In this case, PSC5 would
-have a "port-number = <0>" property, and PSC1 would have "port-number = <1>".
-
-PSC in i2s mode: The mpc5200 and mpc5200b PSCs are not compatible when in
-i2s mode. An 'mpc5200b-psc-i2s' node cannot include 'mpc5200-psc-i2s' in the
-compatible field.
-
-7) GPIO controller nodes
-Each GPIO controller node should have the empty property gpio-controller and
-#gpio-cells set to 2. First cell is the GPIO number which is interpreted
-according to the bit numbers in the GPIO control registers. The second cell
-is for flags which is currently unsused.
-
-8) FEC nodes
-The FEC node can specify one of the following properties to configure
-the MII link:
-"fsl,7-wire-mode" - An empty property that specifies the link uses 7-wire
- mode instead of MII
-"current-speed" - Specifies that the MII should be configured for a fixed
- speed. This property should contain two cells. The
- first cell specifies the speed in Mbps and the second
- should be '0' for half duplex and '1' for full duplex
-"phy-handle" - Contains a phandle to an Ethernet PHY.
-
-IV - Extra Notes
-================
-
-1. Interrupt mapping
---------------------
-The mpc5200 pic driver splits hardware IRQ numbers into two levels. The
-split reflects the layout of the PIC hardware itself, which groups
-interrupts into one of three groups; CRIT, MAIN or PERP. Also, the
-Bestcomm dma engine has it's own set of interrupt sources which are
-cascaded off of peripheral interrupt 0, which the driver interprets as a
-fourth group, SDMA.
-
-The interrupts property for device nodes using the mpc5200 pic consists
-of three cells; <L1 L2 level>
-
- L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
- L2 := interrupt number; directly mapped from the value in the
- "ICTL PerStat, MainStat, CritStat Encoded Register"
- level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
-
-2. Shared registers
--------------------
-Some SoC devices share registers between them. ie. the i2c devices use
-a single clock control register, and almost all device are affected by
-the port_config register. Devices which need to manipulate shared regs
-should look to the parent SoC node. The soc node is responsible
-for arbitrating all shared register access.
^ permalink raw reply related
* Re: [PATCH 1/3] powerpc: bare minimum checkpoint/restart implementation
From: Oren Laadan @ 2009-01-30 0:11 UTC (permalink / raw)
To: Nathan Lynch; +Cc: containers, linuxppc-dev
In-Reply-To: <20090129214035.GB6913@localdomain>
Nathan Lynch wrote:
> Hey Oren, thanks for taking a look.
>
> Oren Laadan wrote:
>> Nathan Lynch wrote:
>>> What doesn't work:
>>> * restarting a 32-bit task from a 64-bit task and vice versa
>> Is there a test to bail if we attempt to checkpoint such tasks ?
>
> No, but I'll add one if it looks too hard to fix for the next round.
>
>
>>> +struct cr_hdr_cpu {
>>> + struct pt_regs pt_regs;
>> It has been suggested (as done in x86/32 code) not to use 'struct pt_regs'
>> because it "can (and has) changed on x86" and because "it only container
>> the registers that the kernel trashes, not all usermode registers".
>>
>> https://lists.linux-foundation.org/pipermail/containers/2008-August/012355.html
>
> Yeah, I considered that discussion, but the situation is different for
> powerpc (someone on linuxppc-dev smack me if I'm wrong here :)
> pt_regs is part of the ABI, and it encompasses all user mode registers
> except for floating point, which are handled separately.
>
>
>>> + /* relevant fields from thread_struct */
>>> + double fpr[32][TS_FPRWIDTH];
>> Can TS_FPRWIDTH change between sub-archs or kernel versions ? If so, it
>> needs to be stated explicitly.
>>
>>> + unsigned int fpscr;
>>> + int fpexc_mode;
>>> + /* unsigned int align_ctl; this is never updated? */
>>> + unsigned long dabr;
>> Are these fields always guarantee to compile to the same number of bytes
>> regardless of 32/64 bit choice of compiler (or sub-arch?) ?
>>
>> In the x86(32/64) architecture we use types with explicit size such as
>> __u32 and the like to ensure that it always compiled to the same
>> size.
>
> Yeah, I'll have to fix these up.
>
>
>
>>> +static void cr_hdr_init(struct cr_hdr *hdr, __s16 type, __s16 len, __u32 parent)
>>> +{
>>> + hdr->type = type;
>>> + hdr->len = len;
>>> + hdr->parent = parent;
>>> +}
>>> +
>> This function is rather generic and useful to non-arch-dependent and other
>> architectures code. Perhaps put in a separate patch ?
>
> Alright. By the way, why are cr_hdr->type and cr_hdr->len signed
> types?
>
No particular reason. I can change that in v14.
>
>>> +int cr_write_cpu(struct cr_ctx *ctx, struct task_struct *t)
>>> +{
>>> + struct cr_hdr_cpu *cpu_hdr;
>>> + struct pt_regs *pt_regs;
>>> + struct cr_hdr cr_hdr;
>>> + u32 parent;
>>> + int ret;
>>> +
>>> + cpu_hdr = cr_hbuf_get(ctx, sizeof(*cpu_hdr));
>>> + if (!cpu_hdr)
>>> + return -ENOMEM;
>>> +
>>> + parent = task_pid_vnr(t);
>>> +
>>> + cr_hdr_init(&cr_hdr, CR_HDR_CPU, sizeof(*cpu_hdr), parent);
>>> +
>>> + /* pt_regs: GPRs, MSR, etc */
>>> + pt_regs = task_pt_regs(t);
>>> + cpu_hdr->pt_regs = *pt_regs;
>>> +
>>> + /* FP state */
>>> + memcpy(cpu_hdr->fpr, t->thread.fpr, sizeof(cpu_hdr->fpr));
>> As note above, is sizeof(cpu_hdr->fpr) the same on all chips ?
>
> It can differ depending on kernel configuration.
So the actual size needs to be explicitly indicated (and compared with).
>
>
>>> +/* restart APIs */
>>> +
>> The restart APIs belong in a separate file: arch/powerpc/mm/restart.c
>
> Explain why, please? This isn't a lot of code, and it seems likely
> that checkpoint and restart paths will share data structures and tend
> to be modified together over time.
This one has little code, but usually that isn't the case, and many of
the data structures shared are anyway exported. Since the split makes
sense in other cases, it makes sense to follow convention.
Personally I don't have a strong opinion on this. However one of the
initial feedbacks for the existing patchset requested that I split the
functionality between files (and to separate commits).
In other words, if nobody else cries, I won't spoil it ;)
>
>
>>> + pr_debug("%s: unexpected thread_hdr contents: 0x%lx\n",
>>> + __func__, (unsigned long)thread_hdr->unimplemented);
>> Given the macro for 'pr_fmt' in include/linux/checkpoint.h, the use of
>> __func__ is redunant.
>
> It seems to me that defining your own pr_fmt in a "public" header like
> that is inappropriate, or at least unconventional. Any file that
> happens to include linux/checkpoint.h will have any prior definitions
> of pr_fmt overridden, no?
>
Hmmm.. didn't think of it this way. Using the pr_debug() there was yet
another feedback from LKML, and it seemed reasonable to me. Can you
think of a case where linux/checkpoint.h will happen to be included
in checkpoint-related code ?
>
>>> + regs = task_pt_regs(current);
>>> + *regs = cpu_hdr->pt_regs;
>>> +
>>> + regs->msr = sanitize_msr(regs->msr);
>>> +
>>> + /* FP state */
>>> + memcpy(current->thread.fpr, cpu_hdr->fpr, sizeof(current->thread.fpr));
>>> + current->thread.fpscr.val = cpu_hdr->fpscr;
>>> + current->thread.fpexc_mode = cpu_hdr->fpexc_mode;
>>> +
>>> + /* debug registers */
>>> + current->thread.dabr = cpu_hdr->dabr;
>> I'm unfamiliar with powerpc; is it necessary to sanitize any of the registers
>> here ? For instance, can the user cause harm with specially crafted values
>> of some registers ?
>
> I had this in mind with the treatment of MSR, but I'll check on the
> others, thanks.
>
>
>>> +int cr_read_mm_context(struct cr_ctx *ctx, struct mm_struct *mm, int rparent)
>>> +{
>>> + struct cr_hdr_mm_context *mm_hdr;
>>> + int ret;
>>> +
>>> + mm_hdr = cr_hbuf_get(ctx, sizeof(*mm_hdr));
>>> + if (!mm_hdr)
>>> + return -ENOMEM;
>>> +
>>> + ret = cr_read_obj_type(ctx, mm_hdr, sizeof(*mm_hdr),
>>> + CR_HDR_MM_CONTEXT);
>>> + if (ret != rparent)
>>> + goto out;
>> Seems like 'ret' isn't set to an error value if the 'goto' executes.
>
> It returns whatever error value cr_read_obj_type() returns. Hrm. I
> guess if the image is garbage, cr_read_obj_type can potentially return
> a non-error value that still isn't the desired value, is that right?
>
True.
Thanks,
Oren.
^ permalink raw reply
* Re: Broken PCI on Sequoia
From: Josh Boyer @ 2009-01-30 0:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Geert Uytterhoeven, Linux/PPC Development
In-Reply-To: <1233267061.18767.5.camel@pasglop>
On Fri, Jan 30, 2009 at 09:11:01AM +1100, Benjamin Herrenschmidt wrote:
>On Thu, 2009-01-29 at 18:37 +0100, Geert Uytterhoeven wrote:
>> Hi Ben, Josh,
>
>
> .../...
>
>> Git-reverting this commit on top of 2.6.29-rc3 makes the crash go away.
>>
>> Perhaps sequoia.dts (and other 44x DTS files) had to be changed, too?
>
>Weird, maybe I have a bug when there is no ISA hole in the DT, I'll have
>a look later today.
Yeah. In fact, I think you have that bug in almost every board. You only
updated Bamboo and Canyonlands with the initial patch and the changelog
says "other boards can be updated separately." Nobody did that. So not
so weird after all.
josh
^ permalink raw reply
* Re: Please pull 'next' branch of linux-2.6-mpc52xx.git
From: Grant Likely @ 2009-01-30 0:29 UTC (permalink / raw)
To: Benjamin Herrenschmidt, linuxppc-dev
In-Reply-To: <fa686aa40901291628k5b58e485n2eadb59d851e7b0e@mail.gmail.com>
Oops, forgot to CC the mailing list.
g.
On Thu, Jan 29, 2009 at 5:28 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
> Hi Ben,
>
> Here is the traditional defconfig update plus a bugfix for mpc5200
> PCI. Please pull into 2.6.29.
>
> Thanks,
> g.
>
> The following changes since commit 18e352e4a73465349711a9324767e1b2453383e2:
> Linus Torvalds (1):
> Linux 2.6.29-rc3
>
> are available in the git repository at:
>
> git://git.secretlab.ca/git/linux-2.6-mpc52xx merge
>
> Grant Likely (2):
> powerpc/5200: update defconfigs
> powerpc/5200: Bugfix for PCI mapping of memory and IMMR
>
> arch/powerpc/configs/52xx/cm5200_defconfig | 83 ++++++++++++++------
> arch/powerpc/configs/52xx/lite5200b_defconfig | 86 +++++++++++++++-----
> arch/powerpc/configs/52xx/motionpro_defconfig | 85 +++++++++++++++-----
> arch/powerpc/configs/52xx/pcm030_defconfig | 82 +++++++++++++------
> arch/powerpc/configs/52xx/tqm5200_defconfig | 89 +++++++++++++++------
> arch/powerpc/configs/mpc5200_defconfig | 104 ++++++++++++++++++-------
> arch/powerpc/platforms/52xx/mpc52xx_pci.c | 24 +++----
> 7 files changed, 396 insertions(+), 157 deletions(-)
>
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: Please pull 'next' branch of linux-2.6-mpc52xx.git
From: Grant Likely @ 2009-01-30 0:31 UTC (permalink / raw)
To: Benjamin Herrenschmidt, linuxppc-dev
In-Reply-To: <fa686aa40901291629q37ca42a9j6c38a3fe26a9d979@mail.gmail.com>
Ummm, I'm batting 1000 today.... Please pull the **MERGE** branch of
linux-2.6-mpc52xx.git tree (The URL below was correct though).
g.
On Thu, Jan 29, 2009 at 5:29 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
> Oops, forgot to CC the mailing list.
>
> g.
>
> On Thu, Jan 29, 2009 at 5:28 PM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> Hi Ben,
>>
>> Here is the traditional defconfig update plus a bugfix for mpc5200
>> PCI. Please pull into 2.6.29.
>>
>> Thanks,
>> g.
>>
>> The following changes since commit 18e352e4a73465349711a9324767e1b2453383e2:
>> Linus Torvalds (1):
>> Linux 2.6.29-rc3
>>
>> are available in the git repository at:
>>
>> git://git.secretlab.ca/git/linux-2.6-mpc52xx merge
>>
>> Grant Likely (2):
>> powerpc/5200: update defconfigs
>> powerpc/5200: Bugfix for PCI mapping of memory and IMMR
>>
>> arch/powerpc/configs/52xx/cm5200_defconfig | 83 ++++++++++++++------
>> arch/powerpc/configs/52xx/lite5200b_defconfig | 86 +++++++++++++++-----
>> arch/powerpc/configs/52xx/motionpro_defconfig | 85 +++++++++++++++-----
>> arch/powerpc/configs/52xx/pcm030_defconfig | 82 +++++++++++++------
>> arch/powerpc/configs/52xx/tqm5200_defconfig | 89 +++++++++++++++------
>> arch/powerpc/configs/mpc5200_defconfig | 104 ++++++++++++++++++-------
>> arch/powerpc/platforms/52xx/mpc52xx_pci.c | 24 +++----
>> 7 files changed, 396 insertions(+), 157 deletions(-)
>>
>>
>> --
>> Grant Likely, B.Sc., P.Eng.
>> Secret Lab Technologies Ltd.
>>
>
>
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH 1/1] powerpc: Fix partition migration hang under load
From: Nathan Lynch @ 2009-01-30 0:38 UTC (permalink / raw)
To: Brian King; +Cc: linuxppc-dev
In-Reply-To: <200901292324.n0TNOktd000814@d03av02.boulder.ibm.com>
Brian King wrote:
>
> While testing partition migration with heavy CPU load using
> shared processors, it was observed that sometimes the migration
> would never complete and would appear to hang. Currently, the
> migration code assumes that if H_SUCCESS is returned from the H_JOIN
> then the migration is complete and the processor is waking up on
> the target system. If there was an outstanding PROD to the processor
> when the H_JOIN is called, however, it will return H_SUCCESS on the source
> system
Hmm, did you determine where that outstanding H_PROD is coming from?
AFAICT this is the only code which uses that hcall, and all processors
should have "consumed" their prods from one migration before another
migration can commence.
Regardless, ACK -- if we were to add another H_PROD call site (or if
there's one I missed) this would be necessary anyway.
^ permalink raw reply
* Re: [PATCH] ucc_geth: Change uec phy id to the same format as gianfar's
From: David Miller @ 2009-01-30 1:28 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev, Haiying.Wang, netdev
In-Reply-To: <FD1B55B4-574B-4B77-889D-FD81D77DCA5E@kernel.crashing.org>
From: Kumar Gala <galak@kernel.crashing.org>
Date: Thu, 29 Jan 2009 12:42:38 -0600
>
> On Jan 29, 2009, at 12:39 PM, Haiying Wang wrote:
>
> > The commit b31a1d8b41513b96e9c7ec2f68c5734cef0b26a4 changes the gianfar's phy id to
> > the format like "mdio@xxxx:xx", but uec still uses the old format like "xxxxxxxx:xx".
> > For the board whose UEC uses gianfar-mdio like MPC8568MDS, the phy can not be attached
> > because of the incompatible phy id format. This patch changes uec's phy id to the same
> > format as gianfar's.
> >
> > Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
> > ---
> > drivers/net/ucc_geth.c | 20 ++++++++++++++++++--
> > drivers/net/ucc_geth.h | 2 ++
> > drivers/net/ucc_geth_mii.c | 12 +++++++++++-
> > drivers/net/ucc_geth_mii.h | 1 +
> > 4 files changed, 32 insertions(+), 3 deletions(-)
>
> David,
>
Applied to net-2.6, thanks.
^ permalink raw reply
* Re: [PATCH] gianfar: Fix Wake-on-LAN support
From: David Miller @ 2009-01-30 1:31 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev, afleming, netdev, jgarzik, peppe.cavallaro
In-Reply-To: <20090128203545.GA13928@oksana.dev.rtsoft.ru>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Date: Wed, 28 Jan 2009 23:35:45 +0300
> commit 0f0ca340e57bd7446855fefd07a64249acf81223 ("phy: power
> management support") caused a regression in the gianfar driver.
>
> Now phylib turns off PHY power during suspend, and thus WOL
> doesn't work anymore.
>
> This patch workarounds the issue by enabling wakeup in the MDIO
> device, i.e. just restores the old behaviour for the gianfar
> driver. Note that this way all PHYs on a given MDIO bus won't
> be turned off during suspend, which isn't good from the power
> saving point of view.
>
> A proper, per netdevice wakeup management support will need
> a bit reworked phylib suspend/resume logic.
>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Applied, thanks Anton.
^ permalink raw reply
* Re: 2.6.28-rt on PowerPC
From: Steven Rostedt @ 2009-01-30 1:51 UTC (permalink / raw)
To: frank.rowand; +Cc: linuxppc-dev, linux-kernel, linux-rt-users
In-Reply-To: <49823A13.50703@am.sony.com>
On Thu, 2009-01-29 at 15:21 -0800, Frank Rowand wrote:
> Steven Rostedt wrote:
> Your email can at an opportune time for me... I was starting to try
> 2.6.28-rt on ARM and quickly came to the conclusion that the arch
> patches weren't the focus yet. But I'm currently side-tracked with
> getting my board to even boot a vanilla 2.6.28 kernel first. Do
> you expect to get to the arches in the next week or two? If not,
> I may head down that path for ARM myself.
I'm going to try to apply the arch patches, but I do not have an arm
board myself. I do have a PPC64 box that works, but that's about it. I
have a powerbook too, but that box has never been able to boot an -rt
kernel. Who knows, maybe this one will boot.
I will create an rt/arm and an rt/ppc branch for the specific changes on
each. I'll try to get them next week (maybe tomorrow if things go better
than planned).
-- Steve
^ permalink raw reply
* Re: Broken PCI on Sequoia
From: Benjamin Herrenschmidt @ 2009-01-30 2:08 UTC (permalink / raw)
To: Josh Boyer; +Cc: Geert Uytterhoeven, Linux/PPC Development
In-Reply-To: <20090130001842.GB3943@zod.rchland.ibm.com>
> Yeah. In fact, I think you have that bug in almost every board. You only
> updated Bamboo and Canyonlands with the initial patch and the changelog
> says "other boards can be updated separately." Nobody did that. So not
> so weird after all.
I still don't see off hand what's wrong in the code..
Geert, any chance you can sprinkle printk's in
ppc4xx_configure_pci_PMMs() ? I'd like to see the arguments to the
various calls to ppc4xx_setup_one_pci_PMM(), and the value of
hose->pci_mem_offset and hose->isa_mem_phys & size.
Cheers,
Ben.
^ permalink raw reply
* Re: 2.6.28-rt on PowerPC
From: Benjamin Herrenschmidt @ 2009-01-30 2:11 UTC (permalink / raw)
To: avorontsov; +Cc: linuxppc-dev, Steven Rostedt, linux-kernel, linux-rt-users
In-Reply-To: <20090129213429.GA29014@oksana.dev.rtsoft.ru>
> This is trivially solved by converting arch/powerpc/sysdev/ipic.c
> back to spinlocks (ipic_lock).
>
> Assuming that converting-back is automatic, there are few other
> chained interrupt controllers you might want to convert-back:
>
> arch/powerpc/sysdev/i8259.c (i8259_lock)
> arch/powerpc/sysdev/mpic.c (mpic_lock)
> arch/powerpc/sysdev/qe_lib/qe_ic.c (qe_ic_lock)
Except that a bunch of those can be both primary and chained... It's
simply not a solution to have to "convert" interrupt controller code to
use a different locking scheme depending on whether they are chained or
primary...
Cheers,
Ben.
^ permalink raw reply
* [RFC/PATCH] powerpc: Rework I$/D$ coherency
From: Benjamin Herrenschmidt @ 2009-01-30 2:26 UTC (permalink / raw)
To: linuxppc-dev
This patch reworks the way we do I and D cache coherency on PowerPC.
The "old" way was split in 3 different parts depending on the processor type:
- Hash with per-page exec support (64-bit and >= POWER4 only) does it
at hashing time, by preventing exec on unclean pages and cleaning pages
on exec faults.
- Everything without per-page exec support (32-bit hash, 8xx, and
64-bit < POWER4) does it for all page going to user space in update_mmu_cache().
- Embedded with per-page exec support does it from do_page_fault() on
exec faults, in a way similar to what the hash code does.
That leads to confusion, and bugs. For example, the method using update_mmu_cache()
is racy on SMP where another processor can see the new PTE and hash it in before
we have cleaned the cache, and then blow trying to execute. This is hard to hit but
I think it has bitten us in the past.
Also, it's inefficient for embedded where we always end up having to do at least
one more page fault.
This reworks the whole thing by moving the cache sync into two main call sites,
though we keep different behaviours depending on the HW capability. The call
sites are set_pte_at() which is now made out of line, and ptep_set_access_flags()
which joins the former in pgtable.c
The base idea for Embedded with per-page exec support, is that we now do the
flush at set_pte_at() time when coming from an exec fault, which allows us
to avoid the double fault problem completely (we can even improve the situation
more by implementing TLB preload in update_mmu_cache() but that's for later).
If for some reason we didn't do it there and we try to execute, we'll hit
the page fault, which will do a minor fault, which will hit ptep_set_access_flags()
to do things like update _PAGE_ACCESSED or _PAGE_DIRTY if needed, we just make
this guys also perform the I/D cache sync for exec faults now. This second path
is the catch all for things that weren't cleaned at set_pte_at() time.
For cpus without per-pag exec support, we always do the sync at set_pte_at(),
thus guaranteeing that when the PTE is visible to other processors, the cache
is clean.
For the 64-bit hash with per-page exec support case, we keep the old mechanism
for now. I'll look into changing it later, once I've reworked a bit how we
use _PAGE_EXEC.
This is also a first step for adding _PAGE_EXEC support for embedded platforms
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/highmem.h | 2
arch/powerpc/include/asm/pgtable-ppc32.h | 53 ------------
arch/powerpc/include/asm/pgtable-ppc64.h | 28 +-----
arch/powerpc/include/asm/pgtable.h | 84 +++++++++++++++++++
arch/powerpc/mm/fault.c | 46 +++-------
arch/powerpc/mm/mem.c | 33 -------
arch/powerpc/mm/pgtable.c | 133 +++++++++++++++++++++++++++++++
7 files changed, 245 insertions(+), 134 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/pgtable-ppc32.h 2009-01-28 15:55:58.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgtable-ppc32.h 2009-01-29 10:14:53.000000000 +1100
@@ -429,6 +429,8 @@ extern int icache_44x_need_flush;
#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
#endif
+#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
+
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
@@ -667,44 +669,6 @@ static inline unsigned long long pte_upd
#endif /* CONFIG_PTE_64BIT */
/*
- * set_pte stores a linux PTE into the linux page table.
- * On machines which use an MMU hash table we avoid changing the
- * _PAGE_HASHPTE bit.
- */
-
-static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
-#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
- pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
-#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
-#if _PAGE_HASHPTE != 0
- if (pte_val(*ptep) & _PAGE_HASHPTE)
- flush_hash_entry(mm, ptep, addr);
-#endif
- __asm__ __volatile__("\
- stw%U0%X0 %2,%0\n\
- eieio\n\
- stw%U0%X0 %L2,%1"
- : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
- : "r" (pte) : "memory");
-#else
- *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
- | (pte_val(pte) & ~_PAGE_HASHPTE));
-#endif
-}
-
-
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
-#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_DEBUG_VM)
- WARN_ON(pte_present(*ptep));
-#endif
- __set_pte_at(mm, addr, ptep, pte);
-}
-
-/*
* 2.6 calls this without flushing the TLB entry; this is wrong
* for our hash-based implementation, we fix that up here.
*/
@@ -744,24 +708,13 @@ static inline void huge_ptep_set_wrprote
}
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
pte_update(ptep, 0, bits);
}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed) { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } \
- __changed; \
-})
-
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
Index: linux-work/arch/powerpc/include/asm/pgtable-ppc64.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pgtable-ppc64.h 2009-01-28 16:00:26.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgtable-ppc64.h 2009-01-29 10:50:58.000000000 +1100
@@ -125,6 +125,8 @@
#define _PTEIDX_SECONDARY 0x8
#define _PTEIDX_GROUP_IX 0x7
+/* To make some generic powerpc code happy */
+#define _PAGE_HWEXEC 0
/*
* POWER4 and newer have per page execute protection, older chips can only
@@ -285,6 +287,10 @@ static inline unsigned long pte_update(s
: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
: "cc" );
+ /* huge pages use the old page table lock */
+ if (!huge)
+ assert_pte_locked(mm, addr);
+
if (old & _PAGE_HASHPTE)
hpte_need_flush(mm, addr, ptep, old, huge);
return old;
@@ -359,23 +365,12 @@ static inline void pte_clear(struct mm_s
pte_update(mm, addr, ptep, ~0UL, 0);
}
-/*
- * set_pte stores a linux PTE into the linux page table.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- if (pte_present(*ptep))
- pte_clear(mm, addr, ptep);
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- *ptep = pte;
-}
/* Set the dirty and/or accessed bits atomically in a linux PTE, this
* function doesn't need to flush the hash entry
*/
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
@@ -392,15 +387,6 @@ static inline void __ptep_set_access_fla
:"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
:"cc");
}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed) { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } \
- __changed; \
-})
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
Index: linux-work/arch/powerpc/include/asm/pgtable.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pgtable.h 2009-01-28 16:46:14.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgtable.h 2009-01-29 13:38:33.000000000 +1100
@@ -6,7 +6,17 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/mmu.h>
#include <asm/page.h>
+
struct mm_struct;
+
+#ifdef CONFIG_DEBUG_VM
+extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr);
+#else /* CONFIG_DEBUG_VM */
+static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+}
+#endif /* !CONFIG_DEBUG_VM */
+
#endif /* !__ASSEMBLY__ */
#if defined(CONFIG_PPC64)
@@ -17,6 +27,80 @@ struct mm_struct;
#ifndef __ASSEMBLY__
+/* Insert a PTE, top-level function is out of line. It uses an inline
+ * low level function in the respective pgtable-* files
+ */
+extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte);
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int percpu)
+{
+#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
+ /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
+ * helper pte_update() which does an atomic update. We need to do that
+ * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
+ * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
+ * the hash bits instead (ie, same as the non-SMP case)
+ */
+ if (percpu)
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ else
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
+
+#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+ /* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we
+ * can just store as long as we do the two halves in the right order
+ * with a barrier in between. This is possible because we take care,
+ * in the hash code, to pre-invalidate if the PTE was already hashed,
+ * which synchronizes us with any concurrent invalidation.
+ * In the percpu case, we also fallback to the simple update preserving
+ * the hash bits
+ */
+ if (percpu) {
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ return;
+ }
+#if _PAGE_HASHPTE != 0
+ if (pte_val(*ptep) & _PAGE_HASHPTE)
+ flush_hash_entry(mm, ptep, addr);
+#endif
+ __asm__ __volatile__("\
+ stw%U0%X0 %2,%0\n\
+ eieio\n\
+ stw%U0%X0 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+
+#elif defined(CONFIG_PPC_STD_MMU_32)
+ /* Third case is 32-bit hash table in UP mode, we need to preserve
+ * the _PAGE_HASHPTE bit since we may not have invalidated the previous
+ * translation in the hash yet (done in a subsequent flush_tlb_xxx())
+ * and see we need to keep track that this PTE needs invalidating
+ */
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+
+#else
+ /* Anything else just stores the PTE normally. That covers all 64-bit
+ * cases, and 32-bit non-hash with 64-bit PTEs in UP mode
+ */
+ *ptep = pte;
+#endif
+}
+
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty);
+
/*
* Macro to mark a page protection value as "uncacheable".
*/
Index: linux-work/arch/powerpc/mm/mem.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/mem.c 2009-01-28 16:41:18.000000000 +1100
+++ linux-work/arch/powerpc/mm/mem.c 2009-01-28 16:41:40.000000000 +1100
@@ -472,40 +472,7 @@ void update_mmu_cache(struct vm_area_str
{
#ifdef CONFIG_PPC_STD_MMU
unsigned long access = 0, trap;
-#endif
- unsigned long pfn = pte_pfn(pte);
- /* handle i-cache coherency */
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
- !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
- pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
-#ifdef CONFIG_8xx
- /* On 8xx, cache control instructions (particularly
- * "dcbst" from flush_dcache_icache) fault as write
- * operation if there is an unpopulated TLB entry
- * for the address in question. To workaround that,
- * we invalidate the TLB here, thus avoiding dcbst
- * misbehaviour.
- */
- _tlbil_va(address, 0 /* 8xx doesn't care about PID */);
-#endif
- /* The _PAGE_USER test should really be _PAGE_EXEC, but
- * older glibc versions execute some code from no-exec
- * pages, which for now we are supporting. If exec-only
- * pages are ever implemented, this will have to change.
- */
- if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER)
- && !test_bit(PG_arch_1, &page->flags)) {
- if (vma->vm_mm == current->active_mm) {
- __flush_dcache_icache((void *) address);
- } else
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- }
-
-#ifdef CONFIG_PPC_STD_MMU
/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
if (!pte_young(pte) || address >= TASK_SIZE)
return;
Index: linux-work/arch/powerpc/mm/pgtable.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/pgtable.c 2009-01-28 16:59:16.000000000 +1100
+++ linux-work/arch/powerpc/mm/pgtable.c 2009-01-29 11:02:56.000000000 +1100
@@ -1,5 +1,6 @@
/*
* This file contains common routines for dealing with free of page tables
+ * Along with common page table handling code
*
* Derived from arch/powerpc/mm/tlb_64.c:
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -115,3 +116,135 @@ void pte_free_finish(void)
pte_free_submit(*batchp);
*batchp = NULL;
}
+
+/*
+ * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
+ */
+static pte_t do_dcache_icache_coherency(pte_t pte)
+{
+ unsigned long pfn = pte_pfn(pte);
+ struct page *page;
+
+ if (unlikely(!pfn_valid(pfn)))
+ return pte;
+ page = pfn_to_page(pfn);
+
+ if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
+ pr_debug("do_dcache_icache_coherency... flushing\n");
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ else
+ pr_debug("do_dcache_icache_coherency... already clean\n");
+ return __pte(pte_val(pte) | _PAGE_HWEXEC);
+}
+
+
+/* has to be a macro because of include dependencies */
+static inline int is_exec_fault(void)
+{
+ return current->thread.regs && TRAP(current->thread.regs) == 0x400;
+}
+
+/* We only try to do i/d cache coherency on stuff that looks like
+ * reasonably "normal" PTEs. We currently require a PTE to be present
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ */
+static inline int pte_looks_normal(pte_t pte)
+{
+ return (pte_val(pte) &
+ (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
+ (_PAGE_PRESENT);
+}
+
+#if defined(CONFIG_PPC_STD_MMU)
+/* Server-style MMU handles coherency when hashing if HW exec permission
+ * is supposed per page (currently 64-bit only). Else, we always flush
+ * valid PTEs in set_pte.
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return set_pte && pte_looks_normal(pte) &&
+ !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+ cpu_has_feature(CPU_FTR_NOEXECUTE));
+}
+#elif _PAGE_HWEXEC == 0
+/* Embedded type MMU without HW exec support (8xx only so far), we flush
+ * the cache for any present PTE
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return set_pte && pte_looks_normal(pte);
+}
+#else
+/* Other embedded CPUs with HW exec support per-page, we flush on exec
+ * fault if HWEXEC is not set
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return pte_looks_normal(pte) && is_exec_fault() &&
+ !(pte_val(pte) & _PAGE_HWEXEC);
+}
+#endif
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ */
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+#ifdef CONFIG_DEBUG_VM
+ WARN_ON(pte_present(*ptep));
+#endif
+ /* Note: mm->context.id might not yet have been assigned as
+ * this context might not have been activated yet when this
+ * is called.
+ */
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ if (pte_need_exec_flush(pte, 1))
+ pte = do_dcache_icache_coherency(pte);
+
+ /* Perform the setting of the PTE */
+ __set_pte_at(mm, addr, ptep, pte, 0);
+}
+
+/*
+ * This is called when relaxing access to a PTE. It's also called in the page
+ * fault path when we don't hit any of the major fault cases, ie, a minor
+ * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have
+ * handled those two for us, we additionally deal with missing execute
+ * permission here on some processors
+ */
+int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty)
+{
+ int changed;
+ if (!dirty && pte_need_exec_flush(entry, 0))
+ entry = do_dcache_icache_coherency(entry);
+ changed = !pte_same(*(ptep), entry);
+ if (changed) {
+ assert_pte_locked(vma->vm_mm, address);
+ __ptep_set_access_flags(ptep, entry);
+ flush_tlb_page_nohash(vma, address);
+ }
+ return changed;
+}
+
+#ifdef CONFIG_DEBUG_VM
+void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ if (mm == &init_mm)
+ return;
+ pgd = mm->pgd + pgd_index(addr);
+ BUG_ON(pgd_none(*pgd));
+ pud = pud_offset(pgd, addr);
+ BUG_ON(pud_none(*pud));
+ pmd = pmd_offset(pud, addr);
+ BUG_ON(!pmd_present(*pmd));
+ BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
+}
+#endif /* CONFIG_DEBUG_VM */
+
Index: linux-work/arch/powerpc/include/asm/highmem.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/highmem.h 2009-01-29 10:11:25.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/highmem.h 2009-01-29 10:20:11.000000000 +1100
@@ -99,7 +99,7 @@ static inline void *kmap_atomic_prot(str
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(*(kmap_pte-idx)));
#endif
- __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+ __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
local_flush_tlb_page(NULL, vaddr);
return (void*) vaddr;
Index: linux-work/arch/powerpc/mm/fault.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/fault.c 2009-01-29 11:40:31.000000000 +1100
+++ linux-work/arch/powerpc/mm/fault.c 2009-01-29 13:38:20.000000000 +1100
@@ -253,45 +253,33 @@ good_area:
#endif /* CONFIG_8xx */
if (is_exec) {
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
- /* protection fault */
+#ifdef CONFIG_PPC_STD_MMU
+ /* Protection fault on exec go straight to failure on
+ * Hash based MMUs as they either don't support per-page
+ * execute permission, or if they do, it's handled already
+ * at the hash level. This test would probably have to
+ * be removed if we change the way this works to make hash
+ * processors use the same I/D cache coherency mechanism
+ * as embedded.
+ */
if (error_code & DSISR_PROTFAULT)
goto bad_area;
+#endif /* CONFIG_PPC_STD_MMU */
+
/*
* Allow execution from readable areas if the MMU does not
* provide separate controls over reading and executing.
+ *
+ * Note: That code used to not be enabled for 4xx/BookE.
+ * It is now as I/D cache coherency for these is done at
+ * set_pte_at() time and I see no reason why the test
+ * below wouldn't be valid on those processors. This -may-
+ * break programs compiled with a really old ABI though.
*/
if (!(vma->vm_flags & VM_EXEC) &&
(cpu_has_feature(CPU_FTR_NOEXECUTE) ||
!(vma->vm_flags & (VM_READ | VM_WRITE))))
goto bad_area;
-#else
- pte_t *ptep;
- pmd_t *pmdp;
-
- /* Since 4xx/Book-E supports per-page execute permission,
- * we lazily flush dcache to icache. */
- ptep = NULL;
- if (get_pteptr(mm, address, &ptep, &pmdp)) {
- spinlock_t *ptl = pte_lockptr(mm, pmdp);
- spin_lock(ptl);
- if (pte_present(*ptep)) {
- struct page *page = pte_page(*ptep);
-
- if (!test_bit(PG_arch_1, &page->flags)) {
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- pte_update(ptep, 0, _PAGE_HWEXEC |
- _PAGE_ACCESSED);
- local_flush_tlb_page(vma, address);
- pte_unmap_unlock(ptep, ptl);
- up_read(&mm->mmap_sem);
- return 0;
- }
- pte_unmap_unlock(ptep, ptl);
- }
-#endif
/* a write */
} else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox