LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] powerpc/nvram: Add spinlock to oops_to_nvram to prevent oops in compression code.
From: Jim Keniston @ 2011-12-02  1:37 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: paulus, linuxppc-dev
In-Reply-To: <20111201124645.24c6e54f@kryten>

On Thu, 2011-12-01 at 12:46 +1100, Anton Blanchard wrote:
> When issuing a system reset we almost always oops in the oops_to_nvram
> code because multiple CPUs are using the deflate work area. Add a
> spinlock to protect it.
> 
> To play it safe I'm using trylock to avoid locking up if the NVRAM
> code oopses. This means we might miss multiple CPUs oopsing at exactly
> the same time but I think it's best to play it safe for now. Once we
> are happy with the reliability we can change it to a full spinlock.
> 
> Signed-off-by: Anton Blanchard <anton@samba.org>

Acked-by: Jim Keniston <jkenisto@us.ibm.com>

> ---
> 
> Index: linux-build/arch/powerpc/platforms/pseries/nvram.c
> ===================================================================
> --- linux-build.orig/arch/powerpc/platforms/pseries/nvram.c	2011-12-01 09:44:27.205568463 +1100
> +++ linux-build/arch/powerpc/platforms/pseries/nvram.c	2011-12-01 12:36:49.334478156 +1100
> @@ -634,6 +634,8 @@ static void oops_to_nvram(struct kmsg_du
>  {
>  	static unsigned int oops_count = 0;
>  	static bool panicking = false;
> +	static DEFINE_SPINLOCK(lock);
> +	unsigned long flags;
>  	size_t text_len;
>  	unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
>  	int rc = -1;
> @@ -664,6 +666,9 @@ static void oops_to_nvram(struct kmsg_du
>  	if (clobbering_unread_rtas_event())
>  		return;
> 
> +	if (!spin_trylock_irqsave(&lock, flags))
> +		return;
> +
>  	if (big_oops_buf) {
>  		text_len = capture_last_msgs(old_msgs, old_len,
>  			new_msgs, new_len, big_oops_buf, big_oops_buf_sz);
> @@ -679,4 +684,6 @@ static void oops_to_nvram(struct kmsg_du
> 
>  	(void) nvram_write_os_partition(&oops_log_partition, oops_buf,
>  		(int) (sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
> +
> +	spin_unlock_irqrestore(&lock, flags);
>  }
> 

^ permalink raw reply

* Re: [PATCH 1/3] serial: make bugs field not specific to 8250 type uarts.
From: Paul Gortmaker @ 2011-12-02  1:32 UTC (permalink / raw)
  To: Alan Cox; +Cc: gregkh, linux-kernel, linux-serial, scottwood, linuxppc-dev
In-Reply-To: <20111202005150.2e9fde43@bob.linux.org.uk>

On Thu, Dec 1, 2011 at 7:51 PM, Alan Cox <alan@linux.intel.com> wrote:
>> Make the bugs field part of the globally visible struct
>> uart_port and remove the 8250 specific one.
>
> Except all the bits in it are 8250 specific things or names that are
> meaningless in generic form - no. I also don't want to encourage flags
> and bug bits. We already have too many and its making the code a mess.
> So right now we want less not more.

The bits in "bugs" are only passed through -- the idea is that there is
no "interpretation" of them by any generic layer -- only that they prop
from the arch down to the driver which knows what they mean.

I can understand the "want less not more" mentality -- I was thinking
the same thing when I was looking at the replication of fields between
uart_port and uart_8250_port, and toying with the idea of helping clean
that up....  (separate topic, to be sure.)

If you have an idea in mind how arch/platform code should cleanly
pass data about known uart bugs to the uart driver, then let me know
what you have in mind.  I've no real attachment to what I proposed
here -- it just happened to be the solution I thought would be the least
offensive.  If there is a better idea floating around, I'll go ahead and
try to implement it.

Thanks,
Paul.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" i=
n
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at =A0http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
From: Benjamin Herrenschmidt @ 2011-12-02  1:26 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: linuxppc-dev, sbest, paulus, anton
In-Reply-To: <20111202001141.GA14860@us.ibm.com>

And an additional comment regarding the rtas bit:

>  #ifdef CONFIG_PPC_SMLPAR
>  void arch_free_page(struct page *page, int order);
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index d5ca823..07cf2cf 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
>  	return 0;
>  }
>  
> +int page_is_rtas(unsigned long pfn)
> +{
> +	unsigned long paddr = (pfn << PAGE_SHIFT);
> +
> +	if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
> +		return 1;
> +
> +	return 0;
> +}

So this only exist whenever rtas.c is compiled... but ...

> +
>  /*
>   * Call early during boot, before mem init or bootmem, to retrieve the RTAS
>   * informations from the device-tree and allocate the RMO buffer for userland
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index c781bbc..d21dbc6 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
>  	hash_preload(vma->vm_mm, address, access, trap);
>  #endif /* CONFIG_PPC_STD_MMU */
>  }
> +
> +extern int page_is_rtas(unsigned long pfn);
> +
> +/*
> + * devmem_is_allowed(): check to see if /dev/mem access to a certain address
> + * is valid. The argument is a physical page number.
> + *
> + * Access has to be given to non-kernel-ram areas as well, these contain the
> + * PCI mmio resources as well as potential bios/acpi data regions.
> + */
> +int devmem_is_allowed(unsigned long pfn)
> +{
> +	if (iomem_is_exclusive(pfn << PAGE_SHIFT))
> +		return 0;
> +	if (!page_is_ram(pfn))
> +		return 1;
> +	if (page_is_rtas(pfn))
> +		return 1;
> +	return 0;
> +}

This calls it unconditionally... you just broke the build of all !rtas
platforms. Additionally, putting an extern definition like that in a .c
file is gross at best....

Please instead, put in a header something like

#ifdef CONFIG_PPC_RTAS
extern int page_is_rtas(unsigned long pfn);
#else
static inline int page_is_rtas(unsigned long pfn) { }
#endif

And while at it, call it page_is_rtas_user_buf(); to make it clear what
we are talking about, ie, not RTAS core per-se but specifically the RMO
buffer.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
From: Benjamin Herrenschmidt @ 2011-12-02  1:23 UTC (permalink / raw)
  To: Sukadev Bhattiprolu; +Cc: linuxppc-dev, sbest, paulus, anton
In-Reply-To: <20111202001141.GA14860@us.ibm.com>

On Thu, 2011-12-01 at 16:11 -0800, Sukadev Bhattiprolu wrote:
> >From aebed2e9fb9fba7dd0a34595780b828d7a545ba2 Mon Sep 17 00:00:00 2001
> From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> Date: Mon, 29 Aug 2011 14:12:08 -0700
> Subject: [PATCH 1/1][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc.
> 
> As described in the help text in the patch, this token restricts general
> access to /dev/mem as a way of increasing security. Specifically, access
> to exclusive IOMEM and kernel RAM is denied unless CONFIG_STRICT_DEVMEM is
> set to 'n'.
> 
> Implement the 'devmem_is_allowed()' interface for POWER. It will be
> called from range_is_allowed() when userpsace attempts to access /dev/mem.
> 
> This patch is based on an earlier patch from Steve Best and with input from
> Paul Mackerras.

A slightly different version of that patch is already in my -next branch
since earlier this week. Please send a followup patch adding the missing
rtas bit.

Note that I've dropped the generic printk change which has nothing to do
in that patch and can/should be submitted separately if it's really
needed.

Cheers,
Ben.


> A test for this patch:
> 
> 	# cat /proc/rtas/rmo_buffer 
> 	000000000f190000 10000
> 
> 	# python -c "print 0x000000000f190000 / 0x10000"
> 	3865
> 
> 	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3865
> 	1+0 records in
> 	1+0 records out
> 	65536 bytes (66 kB) copied, 0.000205235 s, 319 MB/s
> 
> 	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3864
> 	dd: reading `/dev/mem': Operation not permitted
> 	0+0 records in
> 	0+0 records out
> 	0 bytes (0 B) copied, 0.000226844 s, 0.0 kB/s
> 
> 	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3866
> 	dd: reading `/dev/mem': Operation not permitted
> 	0+0 records in
> 	0+0 records out
> 	0 bytes (0 B) copied, 0.00023542 s, 0.0 kB/s
> 
> 	# dd if=/dev/mem of=/tmp/foo
> 	dd: reading `/dev/mem': Operation not permitted
> 	0+0 records in
> 	0+0 records out
> 	0 bytes (0 B) copied, 0.00022519 s, 0.0 kB/s
> 
> Changelog[v2]:
> 	- [Anton Blanchard] Punch a hole in devmem to allow librtas/dlpar
> 	  tools access to /dev/mem.
> 
> Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
> ---
>  arch/powerpc/Kconfig.debug      |   12 ++++++++++++
>  arch/powerpc/include/asm/page.h |    1 +
>  arch/powerpc/kernel/rtas.c      |   10 ++++++++++
>  arch/powerpc/mm/mem.c           |   20 ++++++++++++++++++++
>  drivers/char/mem.c              |    5 +++--
>  5 files changed, 46 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 067cb84..1cf1b00 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -298,4 +298,16 @@ config PPC_EARLY_DEBUG_CPM_ADDR
>  	  platform probing is done, all platforms selected must
>  	  share the same address.
>  
> +config STRICT_DEVMEM
> +	def_bool y
> +	prompt "Filter access to /dev/mem"
> +	help
> +	  This option restricts access to /dev/mem.  If this option is
> +	  disabled, you allow userspace access to all memory, including
> +	  kernel and userspace memory. Accidental memory access is likely
> +	  to be disastrous.
> +	  Memory access is required for experts who want to debug the kernel.
> +
> +	  If you are unsure, say Y.
> +
>  endmenu
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 2cd664e..dc2ec96 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -261,6 +261,7 @@ extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
>  extern void copy_user_page(void *to, void *from, unsigned long vaddr,
>  		struct page *p);
>  extern int page_is_ram(unsigned long pfn);
> +extern int devmem_is_allowed(unsigned long pfn);
>  
>  #ifdef CONFIG_PPC_SMLPAR
>  void arch_free_page(struct page *page, int order);
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index d5ca823..07cf2cf 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
>  	return 0;
>  }
>  
> +int page_is_rtas(unsigned long pfn)
> +{
> +	unsigned long paddr = (pfn << PAGE_SHIFT);
> +
> +	if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
> +		return 1;
> +
> +	return 0;
> +}
> +
>  /*
>   * Call early during boot, before mem init or bootmem, to retrieve the RTAS
>   * informations from the device-tree and allocate the RMO buffer for userland
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index c781bbc..d21dbc6 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
>  	hash_preload(vma->vm_mm, address, access, trap);
>  #endif /* CONFIG_PPC_STD_MMU */
>  }
> +
> +extern int page_is_rtas(unsigned long pfn);
> +
> +/*
> + * devmem_is_allowed(): check to see if /dev/mem access to a certain address
> + * is valid. The argument is a physical page number.
> + *
> + * Access has to be given to non-kernel-ram areas as well, these contain the
> + * PCI mmio resources as well as potential bios/acpi data regions.
> + */
> +int devmem_is_allowed(unsigned long pfn)
> +{
> +	if (iomem_is_exclusive(pfn << PAGE_SHIFT))
> +		return 0;
> +	if (!page_is_ram(pfn))
> +		return 1;
> +	if (page_is_rtas(pfn))
> +		return 1;
> +	return 0;
> +}
> diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> index 8fc04b4..64917e8 100644
> --- a/drivers/char/mem.c
> +++ b/drivers/char/mem.c
> @@ -29,6 +29,7 @@
>  
>  #include <asm/uaccess.h>
>  #include <asm/io.h>
> +#include <asm/page.h>
>  
>  #ifdef CONFIG_IA64
>  # include <linux/efi.h>
> @@ -66,8 +67,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
>  	while (cursor < to) {
>  		if (!devmem_is_allowed(pfn)) {
>  			printk(KERN_INFO
> -		"Program %s tried to access /dev/mem between %Lx->%Lx.\n",
> -				current->comm, from, to);
> +		"Program %s tried to access /dev/mem between %Lx->%Lx and "
> +			"pfn %lu.\n", current->comm, from, to, pfn);
>  			return 0;
>  		}
>  		cursor += PAGE_SIZE;

^ permalink raw reply

* Re: [PATCH 3/3] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Alan Cox @ 2011-12-02  0:57 UTC (permalink / raw)
  To: Paul Gortmaker
  Cc: gregkh, linux-kernel, linux-serial, scottwood, linuxppc-dev
In-Reply-To: <1322783258-20443-4-git-send-email-paul.gortmaker@windriver.com>


> @@ -1553,7 +1554,15 @@ static void serial8250_handle_port(struct
> uart_8250_port *up) 
>  	spin_lock_irqsave(&up->port.lock, flags);
>  
> -	status = serial_inp(up, UART_LSR);
> +	/* Workaround for IRQ storm errata on break with Freescale
> 16550 */
> +	if (UART_BUG_FSLBK & up->port.bugs && up->lsr_last &
> UART_LSR_BI) {
> +		up->lsr_last &= ~UART_LSR_BI;
> +		serial_inp(up, UART_RX);
> +		spin_unlock_irqrestore(&up->port.lock, flags);
> +		return;
> +	}
> +
> +	status = up->lsr_last = serial_inp(up, UART_LSR);

We've now had a recent pile of IRQ function changes adding more quirk
bits and special casing. This doesn't scale. We either need to make
handle_port a method the specific drivers can override or you could
hide the mess in your serial_inp implementation and not touch any core
code.

I really don't mind which but I suspect dealing with it in your
serial_inp handler so that when you read UART_LSR you do the fixup
might be simplest providing you can just do that.

Sorting out a ->handle_port override is probably ultimately the right
thing to do and then we can push some of the other funnies out further.

At this point it's becoming increasingly clear that 8250 UART cloners
are both very bad at cloning the things accurately, and very busy adding
extra useful features so we need to start to treat 8250.c as a library
you can wrap.

Alan

^ permalink raw reply

* Re: [PATCH 1/3] serial: make bugs field not specific to 8250 type uarts.
From: Alan Cox @ 2011-12-02  0:51 UTC (permalink / raw)
  To: Paul Gortmaker
  Cc: gregkh, linux-kernel, linux-serial, scottwood, linuxppc-dev
In-Reply-To: <1322783258-20443-2-git-send-email-paul.gortmaker@windriver.com>

> Make the bugs field part of the globally visible struct
> uart_port and remove the 8250 specific one.

Except all the bits in it are 8250 specific things or names that are
meaningless in generic form - no. I also don't want to encourage flags
and bug bits. We already have too many and its making the code a mess.
So right now we want less not more.

^ permalink raw reply

* Re: [RFC][PATCH] update FSL 16550 nodes to have...
From: Paul Gortmaker @ 2011-12-02  0:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <1322510541-30688-1-git-send-email-galak@kernel.crashing.org>

On Mon, Nov 28, 2011 at 3:02 PM, Kumar Gala <galak@kernel.crashing.org> wrote:
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> * Need to fixup the commit message

I had this written when I was thinking of re-sending the dts
with the other three, that is before I realized the dts patch
would then overwhelm the other patches completely.  :)

P.

----------------
    ppc: update FSL 16550 nodes to have fsl,ns16550 compat entry

    There is an errata relating to break handling on some of
    the Freescale 16550 implementations.  By marking the nodes
    with a fsl prefix, we can use that to know when to enable
    the errata handling.
----------------

^ permalink raw reply

* Re: [PATCH 3/3] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Kumar Gala @ 2011-12-02  0:17 UTC (permalink / raw)
  To: Paul Gortmaker
  Cc: gregkh, linux-kernel, linux-serial, Scott Wood, linuxppc-dev,
	alan
In-Reply-To: <4ED81632.3030809@windriver.com>


On Dec 1, 2011, at 6:05 PM, Paul Gortmaker wrote:

> On 11-12-01 06:51 PM, Scott Wood wrote:
>> On 12/01/2011 05:47 PM, Paul Gortmaker wrote:
>>> diff --git a/include/linux/serial_8250.h =
b/include/linux/serial_8250.h
>>> index 8c660af..b0f4042 100644
>>> --- a/include/linux/serial_8250.h
>>> +++ b/include/linux/serial_8250.h
>>> @@ -18,6 +18,11 @@
>>> #define UART_BUG_TXEN	(1 << 1)	/* buggy TX IIR status =
*/
>>> #define UART_BUG_NOMSR	(1 << 2)	/* buggy MSR status bits =
(Au1x00) */
>>> #define UART_BUG_THRE	(1 << 3)	/* buggy THRE =
reassertion */
>>> +#ifdef CONFIG_PPC32
>>> +#define UART_BUG_FSLBK	(1 << 4)	/* buggy FSL break IRQ =
storm */
>>> +#else	/* help GCC optimize away IRQ handler errata code for =
ARCH !=3D PPC32 */
>>> +#define UART_BUG_FSLBK	0
>>> +#endif
>>=20
>> I believe this bug still exists on our 64-bit chips.
>=20
> OK, I'll simply change the above to CONFIG_PPC then.

It does, the bug is in the uart IP which I don't think we ever plan on =
fixing, so 32 or 64-bit parts will have it for ever and ever ;)

- k=

^ permalink raw reply

* [PATCH][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc
From: Sukadev Bhattiprolu @ 2011-12-02  0:11 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, sbest, paulus, anton

>From aebed2e9fb9fba7dd0a34595780b828d7a545ba2 Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Mon, 29 Aug 2011 14:12:08 -0700
Subject: [PATCH 1/1][v2] Enable CONFIG_STRICT_DEVMEM support for Powerpc.

As described in the help text in the patch, this token restricts general
access to /dev/mem as a way of increasing security. Specifically, access
to exclusive IOMEM and kernel RAM is denied unless CONFIG_STRICT_DEVMEM is
set to 'n'.

Implement the 'devmem_is_allowed()' interface for POWER. It will be
called from range_is_allowed() when userpsace attempts to access /dev/mem.

This patch is based on an earlier patch from Steve Best and with input from
Paul Mackerras.

A test for this patch:

	# cat /proc/rtas/rmo_buffer 
	000000000f190000 10000

	# python -c "print 0x000000000f190000 / 0x10000"
	3865

	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3865
	1+0 records in
	1+0 records out
	65536 bytes (66 kB) copied, 0.000205235 s, 319 MB/s

	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3864
	dd: reading `/dev/mem': Operation not permitted
	0+0 records in
	0+0 records out
	0 bytes (0 B) copied, 0.000226844 s, 0.0 kB/s

	# dd if=/dev/mem of=/tmp/foo count=1 bs=64k skip=3866
	dd: reading `/dev/mem': Operation not permitted
	0+0 records in
	0+0 records out
	0 bytes (0 B) copied, 0.00023542 s, 0.0 kB/s

	# dd if=/dev/mem of=/tmp/foo
	dd: reading `/dev/mem': Operation not permitted
	0+0 records in
	0+0 records out
	0 bytes (0 B) copied, 0.00022519 s, 0.0 kB/s

Changelog[v2]:
	- [Anton Blanchard] Punch a hole in devmem to allow librtas/dlpar
	  tools access to /dev/mem.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
 arch/powerpc/Kconfig.debug      |   12 ++++++++++++
 arch/powerpc/include/asm/page.h |    1 +
 arch/powerpc/kernel/rtas.c      |   10 ++++++++++
 arch/powerpc/mm/mem.c           |   20 ++++++++++++++++++++
 drivers/char/mem.c              |    5 +++--
 5 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 067cb84..1cf1b00 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -298,4 +298,16 @@ config PPC_EARLY_DEBUG_CPM_ADDR
 	  platform probing is done, all platforms selected must
 	  share the same address.
 
+config STRICT_DEVMEM
+	def_bool y
+	prompt "Filter access to /dev/mem"
+	help
+	  This option restricts access to /dev/mem.  If this option is
+	  disabled, you allow userspace access to all memory, including
+	  kernel and userspace memory. Accidental memory access is likely
+	  to be disastrous.
+	  Memory access is required for experts who want to debug the kernel.
+
+	  If you are unsure, say Y.
+
 endmenu
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 2cd664e..dc2ec96 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -261,6 +261,7 @@ extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
 extern void copy_user_page(void *to, void *from, unsigned long vaddr,
 		struct page *p);
 extern int page_is_ram(unsigned long pfn);
+extern int devmem_is_allowed(unsigned long pfn);
 
 #ifdef CONFIG_PPC_SMLPAR
 void arch_free_page(struct page *page, int order);
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index d5ca823..07cf2cf 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -937,6 +937,16 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 	return 0;
 }
 
+int page_is_rtas(unsigned long pfn)
+{
+	unsigned long paddr = (pfn << PAGE_SHIFT);
+
+	if (paddr >= rtas_rmo_buf && paddr < (rtas_rmo_buf + RTAS_RMOBUF_MAX))
+		return 1;
+
+	return 0;
+}
+
 /*
  * Call early during boot, before mem init or bootmem, to retrieve the RTAS
  * informations from the device-tree and allocate the RMO buffer for userland
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index c781bbc..d21dbc6 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -549,3 +549,23 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
 	hash_preload(vma->vm_mm, address, access, trap);
 #endif /* CONFIG_PPC_STD_MMU */
 }
+
+extern int page_is_rtas(unsigned long pfn);
+
+/*
+ * devmem_is_allowed(): check to see if /dev/mem access to a certain address
+ * is valid. The argument is a physical page number.
+ *
+ * Access has to be given to non-kernel-ram areas as well, these contain the
+ * PCI mmio resources as well as potential bios/acpi data regions.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+	if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+		return 0;
+	if (!page_is_ram(pfn))
+		return 1;
+	if (page_is_rtas(pfn))
+		return 1;
+	return 0;
+}
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 8fc04b4..64917e8 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -29,6 +29,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/page.h>
 
 #ifdef CONFIG_IA64
 # include <linux/efi.h>
@@ -66,8 +67,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
 	while (cursor < to) {
 		if (!devmem_is_allowed(pfn)) {
 			printk(KERN_INFO
-		"Program %s tried to access /dev/mem between %Lx->%Lx.\n",
-				current->comm, from, to);
+		"Program %s tried to access /dev/mem between %Lx->%Lx and "
+			"pfn %lu.\n", current->comm, from, to, pfn);
 			return 0;
 		}
 		cursor += PAGE_SIZE;
-- 
1.7.0.4

^ permalink raw reply related

* Re: [PATCH 3/3] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Paul Gortmaker @ 2011-12-02  0:05 UTC (permalink / raw)
  To: Scott Wood; +Cc: gregkh, linux-kernel, linux-serial, linuxppc-dev, alan
In-Reply-To: <4ED812E4.60905@freescale.com>

On 11-12-01 06:51 PM, Scott Wood wrote:
> On 12/01/2011 05:47 PM, Paul Gortmaker wrote:
>> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
>> index 8c660af..b0f4042 100644
>> --- a/include/linux/serial_8250.h
>> +++ b/include/linux/serial_8250.h
>> @@ -18,6 +18,11 @@
>>  #define UART_BUG_TXEN	(1 << 1)	/* buggy TX IIR status */
>>  #define UART_BUG_NOMSR	(1 << 2)	/* buggy MSR status bits (Au1x00) */
>>  #define UART_BUG_THRE	(1 << 3)	/* buggy THRE reassertion */
>> +#ifdef CONFIG_PPC32
>> +#define UART_BUG_FSLBK	(1 << 4)	/* buggy FSL break IRQ storm */
>> +#else	/* help GCC optimize away IRQ handler errata code for ARCH != PPC32 */
>> +#define UART_BUG_FSLBK	0
>> +#endif
> 
> I believe this bug still exists on our 64-bit chips.

OK, I'll simply change the above to CONFIG_PPC then.

Thanks,
Paul.

> 
> -Scott
> 

^ permalink raw reply

* Re: [PATCH 3/3] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Scott Wood @ 2011-12-01 23:51 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: gregkh, linux-kernel, linux-serial, linuxppc-dev, alan
In-Reply-To: <1322783258-20443-4-git-send-email-paul.gortmaker@windriver.com>

On 12/01/2011 05:47 PM, Paul Gortmaker wrote:
> diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
> index 8c660af..b0f4042 100644
> --- a/include/linux/serial_8250.h
> +++ b/include/linux/serial_8250.h
> @@ -18,6 +18,11 @@
>  #define UART_BUG_TXEN	(1 << 1)	/* buggy TX IIR status */
>  #define UART_BUG_NOMSR	(1 << 2)	/* buggy MSR status bits (Au1x00) */
>  #define UART_BUG_THRE	(1 << 3)	/* buggy THRE reassertion */
> +#ifdef CONFIG_PPC32
> +#define UART_BUG_FSLBK	(1 << 4)	/* buggy FSL break IRQ storm */
> +#else	/* help GCC optimize away IRQ handler errata code for ARCH != PPC32 */
> +#define UART_BUG_FSLBK	0
> +#endif

I believe this bug still exists on our 64-bit chips.

-Scott

^ permalink raw reply

* [PATCH 3/3] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Paul Gortmaker @ 2011-12-01 23:47 UTC (permalink / raw)
  To: gregkh, alan, galak, scottwood; +Cc: linuxppc-dev, linux-kernel, linux-serial
In-Reply-To: <1322783258-20443-1-git-send-email-paul.gortmaker@windriver.com>

Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
chips seems to cause a short lived IRQ storm (/proc/interrupts
typically shows somewhere between 300 and 1500 events).  Unfortunately
this renders SysRQ over the serial console completely inoperable.

The suggested workaround in the errata is to read the Rx register,
wait one character period, and then read the Rx register again.
We achieve this by tracking the old LSR value, and on the subsequent
interrupt event after a break, we don't read LSR, instead we just
read the RBR again and return immediately.

The "fsl,ns16550" is used in the compatible field of the serial
device to mark UARTs known to have this issue.

Thanks to Scott Wood for providing the errata data which led to
a much cleaner fix.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 arch/powerpc/kernel/legacy_serial.c |   11 +++++++++++
 drivers/tty/serial/8250.c           |   11 ++++++++++-
 include/linux/serial_8250.h         |    5 +++++
 3 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index c7b5afe..dd232ca 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -476,6 +476,15 @@ static void __init fixup_port_mmio(int index,
 	port->membase = ioremap(port->mapbase, 0x100);
 }
 
+static void __init fixup_port_bugs(int index,
+				   struct device_node *np,
+				   struct plat_serial8250_port *port)
+{
+	DBG("fixup_port_bugs(%d)\n", index);
+
+	if (of_device_is_compatible(np, "fsl,ns16550"))
+		port->bugs = UART_BUG_FSLBK;
+}
 /*
  * This is called as an arch initcall, hopefully before the PCI bus is
  * probed and/or the 8250 driver loaded since we need to register our
@@ -512,6 +521,8 @@ static int __init serial_dev_init(void)
 			fixup_port_pio(i, np, port);
 		if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
 			fixup_port_mmio(i, np, port);
+
+		fixup_port_bugs(i, np, port);
 	}
 
 	DBG("Registering platform serial ports\n");
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index f99f27c..32e9821 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -142,6 +142,7 @@ struct uart_8250_port {
 	unsigned char		mcr_mask;	/* mask of user bits */
 	unsigned char		mcr_force;	/* mask of forced bits */
 	unsigned char		cur_iotype;	/* Running I/O type */
+	unsigned char		lsr_last;	/* LSR of last IRQ event */
 
 	/*
 	 * Some bits in registers are cleared on a read, so they must
@@ -1553,7 +1554,15 @@ static void serial8250_handle_port(struct uart_8250_port *up)
 
 	spin_lock_irqsave(&up->port.lock, flags);
 
-	status = serial_inp(up, UART_LSR);
+	/* Workaround for IRQ storm errata on break with Freescale 16550 */
+	if (UART_BUG_FSLBK & up->port.bugs && up->lsr_last & UART_LSR_BI) {
+		up->lsr_last &= ~UART_LSR_BI;
+		serial_inp(up, UART_RX);
+		spin_unlock_irqrestore(&up->port.lock, flags);
+		return;
+	}
+
+	status = up->lsr_last = serial_inp(up, UART_LSR);
 
 	DEBUG_INTR("status = %x...", status);
 
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 8c660af..b0f4042 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -18,6 +18,11 @@
 #define UART_BUG_TXEN	(1 << 1)	/* buggy TX IIR status */
 #define UART_BUG_NOMSR	(1 << 2)	/* buggy MSR status bits (Au1x00) */
 #define UART_BUG_THRE	(1 << 3)	/* buggy THRE reassertion */
+#ifdef CONFIG_PPC32
+#define UART_BUG_FSLBK	(1 << 4)	/* buggy FSL break IRQ storm */
+#else	/* help GCC optimize away IRQ handler errata code for ARCH != PPC32 */
+#define UART_BUG_FSLBK	0
+#endif
 
 /*
  * This is the platform device platform_data structure
-- 
1.7.7

^ permalink raw reply related

* [PATCH 1/3] serial: make bugs field not specific to 8250 type uarts.
From: Paul Gortmaker @ 2011-12-01 23:47 UTC (permalink / raw)
  To: gregkh, alan, galak, scottwood; +Cc: linuxppc-dev, linux-kernel, linux-serial
In-Reply-To: <1322783258-20443-1-git-send-email-paul.gortmaker@windriver.com>

There is a struct uart_8250_port that is private to 8250.c
itself, and it had a bugs field.  But there is no reason to
assume that hardware bugs are unique to 8250 type UARTS.

Make the bugs field part of the globally visible struct
uart_port and remove the 8250 specific one.

The value in doing so is that it helps pave the way for
allowing arch or platform specific code to pass in information
to the specific uart drivers about uart bugs known to impact
certain platforms that would otherwise be hard to detect from
within the context of the driver itself.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 drivers/tty/serial/8250.c   |   25 ++++++++++++-------------
 include/linux/serial_core.h |    1 +
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index eeadf1b..7c94dbc 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -134,7 +134,6 @@ struct uart_8250_port {
 	struct timer_list	timer;		/* "no irq" timer */
 	struct list_head	list;		/* ports on this IRQ */
 	unsigned short		capabilities;	/* port capabilities */
-	unsigned short		bugs;		/* port bugs */
 	unsigned int		tx_loadsz;	/* transmit fifo load size */
 	unsigned char		acr;
 	unsigned char		ier;
@@ -828,7 +827,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
 		 * when DLL is 0.
 		 */
 		if (id3 == 0x52 && rev == 0x01)
-			up->bugs |= UART_BUG_QUOT;
+			up->port.bugs |= UART_BUG_QUOT;
 		return;
 	}
 
@@ -1102,7 +1101,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 	spin_lock_irqsave(&up->port.lock, flags);
 
 	up->capabilities = 0;
-	up->bugs = 0;
+	up->port.bugs = 0;
 
 	if (!(up->port.flags & UPF_BUGGY_UART)) {
 		/*
@@ -1337,7 +1336,7 @@ static void serial8250_start_tx(struct uart_port *port)
 		up->ier |= UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
 
-		if (up->bugs & UART_BUG_TXEN) {
+		if (port->bugs & UART_BUG_TXEN) {
 			unsigned char lsr;
 			lsr = serial_in(up, UART_LSR);
 			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
@@ -1373,7 +1372,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 		container_of(port, struct uart_8250_port, port);
 
 	/* no MSR capabilities */
-	if (up->bugs & UART_BUG_NOMSR)
+	if (port->bugs & UART_BUG_NOMSR)
 		return;
 
 	up->ier |= UART_IER_MSI;
@@ -2089,7 +2088,7 @@ static int serial8250_startup(struct uart_port *port)
 		 * kick the UART on a regular basis.
 		 */
 		if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
-			up->bugs |= UART_BUG_THRE;
+			port->bugs |= UART_BUG_THRE;
 			pr_debug("ttyS%d - using backup timer\n",
 				 serial_index(port));
 		}
@@ -2099,7 +2098,7 @@ static int serial8250_startup(struct uart_port *port)
 	 * The above check will only give an accurate result the first time
 	 * the port is opened so this value needs to be preserved.
 	 */
-	if (up->bugs & UART_BUG_THRE) {
+	if (port->bugs & UART_BUG_THRE) {
 		up->timer.function = serial8250_backup_timeout;
 		up->timer.data = (unsigned long)up;
 		mod_timer(&up->timer, jiffies +
@@ -2162,13 +2161,13 @@ static int serial8250_startup(struct uart_port *port)
 	serial_outp(up, UART_IER, 0);
 
 	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
-		if (!(up->bugs & UART_BUG_TXEN)) {
-			up->bugs |= UART_BUG_TXEN;
+		if (!(port->bugs & UART_BUG_TXEN)) {
+			port->bugs |= UART_BUG_TXEN;
 			pr_debug("ttyS%d - enabling bad tx status workarounds\n",
 				 serial_index(port));
 		}
 	} else {
-		up->bugs &= ~UART_BUG_TXEN;
+		port->bugs &= ~UART_BUG_TXEN;
 	}
 
 dont_test_tx_en:
@@ -2323,7 +2322,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 	/*
 	 * Oxford Semi 952 rev B workaround
 	 */
-	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
+	if (port->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
 		quot++;
 
 	if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
@@ -2390,7 +2389,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 	 * CTS flow control flag and modem status interrupts
 	 */
 	up->ier &= ~UART_IER_MSI;
-	if (!(up->bugs & UART_BUG_NOMSR) &&
+	if (!(port->bugs & UART_BUG_NOMSR) &&
 			UART_ENABLE_MS(&up->port, termios->c_cflag))
 		up->ier |= UART_IER_MSI;
 	if (up->capabilities & UART_CAP_UUE)
@@ -2666,7 +2665,7 @@ static void serial8250_config_port(struct uart_port *port, int flags)
 
 	/* if access method is AU, it is a 16550 with a quirk */
 	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
-		up->bugs |= UART_BUG_NOMSR;
+		port->bugs |= UART_BUG_NOMSR;
 
 	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
 		autoconfig_irq(up);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index eadf33d..791536c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -323,6 +323,7 @@ struct uart_port {
 
 	unsigned int		read_status_mask;	/* driver specific */
 	unsigned int		ignore_status_mask;	/* driver specific */
+	unsigned short		bugs;			/* driver specific */
 	struct uart_state	*state;			/* pointer to parent state */
 	struct uart_icount	icount;			/* statistics */
 
-- 
1.7.7

^ permalink raw reply related

* [PATCH 0/3] RFC Fix Fsl 8250 BRK bug via letting plat code set bugs
From: Paul Gortmaker @ 2011-12-01 23:47 UTC (permalink / raw)
  To: gregkh, alan, galak, scottwood; +Cc: linuxppc-dev, linux-kernel, linux-serial

This is a respin of an earlier patch[1] that enabled a workaround
via Kconfig for an errata issue when using BRK on FSL 16550 UARTs.

In this version, the 8250 specific bug field is moved to the generic
uart_port struct, since hardware bugs aren't the unique domain of 
just the 8250 class of uarts.

Then the ability to set a known bugs value via the platform_device entry
point is added, so that it can be set externally vs. requiring some sort
of autodetection from the actual driver(s).

Then, the FSL errata fix is added to 8250.c by using the above support.
An entry in a DTS file is used to flag boards/platforms with the issue.
It is also added in a way that is optimized away for other architectures.

Kumar has a patch pending[2] that updates all the dts files.  I've not
included it here, so that review focus can be on the implementation.

I've re-tested it on an sbc8641D, where sysrq was useless before; with
this fix, it works as expected.

Thanks,
Paul.

[1] http://patchwork.ozlabs.org/patch/46609/
[2] http://patchwork.ozlabs.org/patch/128070/

--------

Paul Gortmaker (3):
  serial: make bugs field not specific to 8250 type uarts.
  serial: allow passing in hardware bug info via platform device
  8250: add workaround for MPC8[356]xx UART break IRQ storm

 arch/powerpc/kernel/legacy_serial.c |   11 ++++++++++
 drivers/tty/serial/8250.c           |   37 +++++++++++++++++++++-------------
 drivers/tty/serial/8250.h           |    5 ----
 include/linux/serial_8250.h         |   11 ++++++++++
 include/linux/serial_core.h         |    1 +
 5 files changed, 46 insertions(+), 19 deletions(-)

-- 
1.7.7

^ permalink raw reply

* [PATCH 2/3] serial: allow passing in hardware bug info via platform device
From: Paul Gortmaker @ 2011-12-01 23:47 UTC (permalink / raw)
  To: gregkh, alan, galak, scottwood; +Cc: linuxppc-dev, linux-kernel, linux-serial
In-Reply-To: <1322783258-20443-1-git-send-email-paul.gortmaker@windriver.com>

The normal arch hook into the 8250 serial world is via passing
in a plat_serial8250_port struct.  However, this struct does
not have a bugs field, so there is no way to have the arch
code pass in info about known uart issues.

Add a bug field to the plat_serial8250_port struct, so that the
arch can pass in this information.  Also don't do a blanket
overwrite of the bugs setting in the 8250.c driver.  Finally,
relocate the known bug #define list to a globally visible header
so that the arch can assign any appropriate values from the list.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 drivers/tty/serial/8250.c   |    3 ++-
 drivers/tty/serial/8250.h   |    5 -----
 include/linux/serial_8250.h |    6 ++++++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index 7c94dbc..f99f27c 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -1101,7 +1101,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
 	spin_lock_irqsave(&up->port.lock, flags);
 
 	up->capabilities = 0;
-	up->port.bugs = 0;
 
 	if (!(up->port.flags & UPF_BUGGY_UART)) {
 		/*
@@ -3075,6 +3074,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 		port.serial_out		= p->serial_out;
 		port.handle_irq		= p->handle_irq;
 		port.set_termios	= p->set_termios;
+		port.bugs		= p->bugs;
 		port.pm			= p->pm;
 		port.dev		= &dev->dev;
 		port.irqflags		|= irqflag;
@@ -3225,6 +3225,7 @@ int serial8250_register_port(struct uart_port *port)
 		uart->port.regshift     = port->regshift;
 		uart->port.iotype       = port->iotype;
 		uart->port.flags        = port->flags | UPF_BOOT_AUTOCONF;
+		uart->port.bugs         = port->bugs;
 		uart->port.mapbase      = port->mapbase;
 		uart->port.private_data = port->private_data;
 		if (port->dev)
diff --git a/drivers/tty/serial/8250.h b/drivers/tty/serial/8250.h
index 6edf4a6..caefe00 100644
--- a/drivers/tty/serial/8250.h
+++ b/drivers/tty/serial/8250.h
@@ -44,11 +44,6 @@ struct serial8250_config {
 #define UART_CAP_UUE	(1 << 12)	/* UART needs IER bit 6 set (Xscale) */
 #define UART_CAP_RTOIE	(1 << 13)	/* UART needs IER bit 4 set (Xscale, Tegra) */
 
-#define UART_BUG_QUOT	(1 << 0)	/* UART has buggy quot LSB */
-#define UART_BUG_TXEN	(1 << 1)	/* UART has buggy TX IIR status */
-#define UART_BUG_NOMSR	(1 << 2)	/* UART has buggy MSR status bits (Au1x00) */
-#define UART_BUG_THRE	(1 << 3)	/* UART has buggy THRE reassertion */
-
 #define PROBE_RSA	(1 << 0)
 #define PROBE_ANY	(~0)
 
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 1f05bbe..8c660af 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -14,6 +14,11 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 
+#define UART_BUG_QUOT	(1 << 0)	/* buggy quot LSB */
+#define UART_BUG_TXEN	(1 << 1)	/* buggy TX IIR status */
+#define UART_BUG_NOMSR	(1 << 2)	/* buggy MSR status bits (Au1x00) */
+#define UART_BUG_THRE	(1 << 3)	/* buggy THRE reassertion */
+
 /*
  * This is the platform device platform_data structure
  */
@@ -30,6 +35,7 @@ struct plat_serial8250_port {
 	unsigned char	hub6;
 	upf_t		flags;		/* UPF_* flags */
 	unsigned int	type;		/* If UPF_FIXED_TYPE */
+	unsigned short	bugs;		/* hardware specific bugs */
 	unsigned int	(*serial_in)(struct uart_port *, int);
 	void		(*serial_out)(struct uart_port *, int, int);
 	void		(*set_termios)(struct uart_port *,
-- 
1.7.7

^ permalink raw reply related

* Re: [PATCH 5/6] powerpc/boot: Add mfdcrx
From: Segher Boessenkool @ 2011-12-01 22:55 UTC (permalink / raw)
  To: David Laight; +Cc: LinuxPPC-dev
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6D8AEF3@saturn3.aculab.com>

>>> +#define mfdcrx(rn) \
>>> +	({	\
>>> +		unsigned long rval; \
>>> +		asm volatile("mfdcrx %0,%1" : "=r"(rval) : "g"(rn)); \
>>> +		rval; \
>>> +	})
>>
>> "g" is never correct on PowerPC, you want "r" here.  You can write
>> this as a static inline btw, you only need the #define stuff when
>> there is an "i" constraint involved.
>
> I think you can still use static inlines even when a
> constraint is one that requires a compile time constant.

Marking a function inline does not guarantee the compiler will
perform inline substitution on it, which you need here.  I don't
think it's a problem with recent GCC in the context of the Linux
kernel though, if you use __always_inline that is.


Segher

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 22:10 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7FA38.6030606@freescale.com>

Scott Wood wrote:
> 
> Does of_find_i2c_device_by_node() do what you want?

Yeah, that'll work.  I wasn't thinking about looking for an i2c device.  Thanks.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Scott Wood @ 2011-12-01 22:05 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F8CE.10801@freescale.com>

On 12/01/2011 03:59 PM, Timur Tabi wrote:
> Scott Wood wrote:
>> Ideally we would have a field in struct device_node that points to
>> struct device.
> 
> I don't think there's a single place in the code where the connection
> between the device and device_node is made.  In fact, I think
> dev->of_node needs to be manually initialized by the driver during
> the OF probe.

The i2c core does this.

Does of_find_i2c_device_by_node() do what you want?

-Scott

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 21:59 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F72F.7050405@freescale.com>

Scott Wood wrote:
> Ideally we would have a field in struct device_node that points to
> struct device.

I don't think there's a single place in the code where the connection between the device and device_node is made.  In fact, I think dev->of_node needs to be manually initialized by the driver during the OF probe.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 21:59 UTC (permalink / raw)
  To: Grant Likely; +Cc: Scott Wood, linuxppc-dev, kumar.gala
In-Reply-To: <CACxGe6sZgG5q6NKgsGaWLyTzWHXNGqHke9nQMyqzw0audS3=tw@mail.gmail.com>

Grant Likely wrote:
> It is better to walk the list of i2c adapters and look for one that
> has the matching node pointer.  It really isn't an expensive operation
> to do it that way.

That's what I was thinking.  I can't figure out how to walk the list, though.  i2c_get_adapter() takes an adapter number, but I don't think this is going to work:

unsigned int i = 0;
struct i2c_adapter adap = i2c_get_adapter(0);

while (adap) {
	if (adap->nr == nr)
		break;
	adap = i2c_get_adapter(++i);
}

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Grant Likely @ 2011-12-01 21:55 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kumar.gala, Timur Tabi
In-Reply-To: <4ED7F72F.7050405@freescale.com>

On Thu, Dec 1, 2011 at 2:52 PM, Scott Wood <scottwood@freescale.com> wrote:
> On 12/01/2011 03:46 PM, Timur Tabi wrote:
>> Scott Wood wrote:
>>
>>> How is this going to interact with other i2c buses (e.g. on a board
>>> FPGA) that might have a conflicting static numbering scheme? =A0Have yo=
u
>>> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
>>> device) can happen before the static SoC i2c buses are added?
>>
>> Hmm.... You have a point there.
>>
>>>> An alternative approach is to create a function like this:
>>>>
>>>> =A0 =A0 struct i2c_adapter *i2c_adapter_from_node(struct device_node *=
np);
>>>>
>>>> I could then just use adap->nr directly.
>>>
>>> If there isn't a way to get a "struct device" from "struct device_node"=
,
>>> we should add it.
>>
>> How do I do that? =A0Scan all the struct devices until I find one where =
dev->of_node =3D=3D np? =A0That seems really inefficient.
>
> Ideally we would have a field in struct device_node that points to
> struct device.

No.  There are cases where multiple devices may reference the same node.

It is better to walk the list of i2c adapters and look for one that
has the matching node pointer.  It really isn't an expensive operation
to do it that way.

g.

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Scott Wood @ 2011-12-01 21:52 UTC (permalink / raw)
  To: Timur Tabi; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F5AA.2040909@freescale.com>

On 12/01/2011 03:46 PM, Timur Tabi wrote:
> Scott Wood wrote:
> 
>> How is this going to interact with other i2c buses (e.g. on a board
>> FPGA) that might have a conflicting static numbering scheme?  Have you
>> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
>> device) can happen before the static SoC i2c buses are added?
> 
> Hmm.... You have a point there.
> 
>>> An alternative approach is to create a function like this:
>>>
>>> 	struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
>>>
>>> I could then just use adap->nr directly.
>>
>> If there isn't a way to get a "struct device" from "struct device_node",
>> we should add it. 
> 
> How do I do that?  Scan all the struct devices until I find one where dev->of_node == np?  That seems really inefficient.

Ideally we would have a field in struct device_node that points to
struct device.

-Scott

^ permalink raw reply

* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 21:46 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F1AE.70806@freescale.com>

Scott Wood wrote:

> How is this going to interact with other i2c buses (e.g. on a board
> FPGA) that might have a conflicting static numbering scheme?  Have you
> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
> device) can happen before the static SoC i2c buses are added?

Hmm.... You have a point there.

>> An alternative approach is to create a function like this:
>>
>> 	struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
>>
>> I could then just use adap->nr directly.
> 
> If there isn't a way to get a "struct device" from "struct device_node",
> we should add it. 

How do I do that?  Scan all the struct devices until I find one where dev->of_node == np?  That seems really inefficient.

-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* Re: ppc4xx simple vs SoC's
From: Benjamin Herrenschmidt @ 2011-12-01 21:39 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <CA+5PVA5xaCa8Tv3MMr1WzQAuLit9KenMoezOKB7ENQSt=fOSOg@mail.gmail.com>

On Thu, 2011-12-01 at 06:44 -0500, Josh Boyer wrote:

> > However, the entry for ppc44x_simple doesn't select any of these,
> > meaning for example, AFAIK, that you don't get EMAC4 etc... I'm
> > surprised things work at all !
> >
> > What am I missing ?
> 
> CONFIG_PPC44x_SIMPLE is selected by the board Kconfig values, which
> also select all of the SoC Kconfig options they need as well.
> ppc44x_simple started as a way to basically avoid duplicating a bunch
> of board.c files, but it's still "driven" from the board options.
> 
> So hopefully that explains how things are working today.  The question
> now is whether you would like something different?

Ok, just getting my head around that stuff, I haven't really looked
since you and Grant I believe came up with the scheme :-) (Was wondering
what to do for currituck, but for now we'll keep it a separate board, at
least until I can decide how to deal with the interrupt quirk).

I just hadn't realized that while we had ppc4xx_simple, we still had
board Kconfig's to enable it.

Cheers,
Ben.

^ permalink raw reply

* Re: [BUG?]3.0-rc4+ftrace+kprobe: set kprobe at instruction 'stwu' lead to system crash/freeze
From: Benjamin Herrenschmidt @ 2011-12-01 21:37 UTC (permalink / raw)
  To: tiejun.chen
  Cc: Jim Keniston, Anton Blanchard, linux-kernel, Steven Rostedt,
	Yong Zhang, paulus, yrl.pp-manager.tt, Masami Hiramatsu,
	linuxppc-dev
In-Reply-To: <4ED75A9A.1030100@windriver.com>

On Thu, 2011-12-01 at 18:44 +0800, tiejun.chen wrote:

> Do you mean we should push the original pt_regs (or that whole exception stack)
> downwards the location the new r1 point? Then its safe to perform this real
> emulated stw instruction. At last we will reroute r1 to that copied exception
> frame to restore as normal. Right?

Right. That way we don't have to modify the (sensitive) restore path, we
only hook around the do_work branch which is a lot easier and less
risky.

> Here I suppose so, I implement this for PPC32 based on the above understanding.
> I take a validation for kprobing do_fork()/show_interrupts(), now looks fine.
> Tomorrow I will go PPC64, and hope its fine as well.
> 
> If everything is good I'll send these patches to linuxppc-dev next week.

Excellent, thanks !

Cheers,
Ben.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox