linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] OpenRISC fixes for 5.9
@ 2020-09-05 13:19 Stafford Horne
  2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:19 UTC (permalink / raw)
  To: LKML; +Cc: Stafford Horne

Changes since v1:

 - Now a series, v1 was only the "Reserve memblock for initrd" patch
 - Added fixes for compiler issues pointed out by the kbuild robot

This is a few fixes found during testing 5.9.

Stafford Horne (3):
  openrisc: Reserve memblock for initrd
  openrisc: Fix cache API compile issue when not inlining
  openrisc: Fix issue with get_user for 64-bit values

 arch/openrisc/include/asm/uaccess.h | 16 ++++++++--------
 arch/openrisc/kernel/setup.c        | 10 ++++++++++
 arch/openrisc/mm/cache.c            |  2 +-
 3 files changed, 19 insertions(+), 9 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/3] openrisc: Reserve memblock for initrd
  2020-09-05 13:19 [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
@ 2020-09-05 13:19 ` Stafford Horne
  2020-09-05 13:25   ` Stafford Horne
  2020-09-06  6:15   ` Mike Rapoport
  2020-09-05 13:19 ` [PATCH v2 2/3] openrisc: Fix cache API compile issue when not inlining Stafford Horne
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:19 UTC (permalink / raw)
  To: LKML
  Cc: Stafford Horne, Jonas Bonn, Stefan Kristiansson, Mike Rapoport,
	Arvind Sankar, Greg Kroah-Hartman, Andrew Morton, openrisc

Recently OpenRISC added support for external initrd images, but I found
some instability when using larger buildroot initrd images. It turned
out that I forgot to reserve the memblock space for the initrd image.

This patch fixes the instability issue by reserving memblock space.

Fixes: ff6c923dbec3 ("openrisc: Add support for external initrd images")
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 arch/openrisc/kernel/setup.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
index b18e775f8be3..13c87f1f872b 100644
--- a/arch/openrisc/kernel/setup.c
+++ b/arch/openrisc/kernel/setup.c
@@ -80,6 +80,16 @@ static void __init setup_memory(void)
 	 */
 	memblock_reserve(__pa(_stext), _end - _stext);
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* Then reserve the initrd, if any */
+	if (initrd_start && (initrd_end > initrd_start)) {
+		unsigned long aligned_start = ALIGN_DOWN(initrd_start, PAGE_SIZE);
+		unsigned long aligned_end = ALIGN(initrd_end, PAGE_SIZE);
+
+		memblock_reserve(__pa(aligned_start), aligned_end - aligned_start);
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/3] openrisc: Fix cache API compile issue when not inlining
  2020-09-05 13:19 [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
  2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
@ 2020-09-05 13:19 ` Stafford Horne
  2020-09-05 13:19 ` [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values Stafford Horne
  2020-09-05 13:24 ` [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
  3 siblings, 0 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:19 UTC (permalink / raw)
  To: LKML; +Cc: Stafford Horne, Jonas Bonn, Stefan Kristiansson, openrisc

I found this when compiling a kbuild random config with GCC 11.  The
config enables CONFIG_DEBUG_SECTION_MISMATCH, which sets CFLAGS
-fno-inline-functions-called-once. This causes the call to cache_loop in
cache.c to not be inlined causing the below compile error.

    In file included from arch/openrisc/mm/cache.c:13:
    arch/openrisc/mm/cache.c: In function 'cache_loop':
    ./arch/openrisc/include/asm/spr.h:16:27: warning: 'asm' operand 0 probably does not match constraints
       16 | #define mtspr(_spr, _val) __asm__ __volatile__ (  \
	  |                           ^~~~~~~
    arch/openrisc/mm/cache.c:25:3: note: in expansion of macro 'mtspr'
       25 |   mtspr(reg, line);
	  |   ^~~~~
    ./arch/openrisc/include/asm/spr.h:16:27: error: impossible constraint in 'asm'
       16 | #define mtspr(_spr, _val) __asm__ __volatile__ (  \
	  |                           ^~~~~~~
    arch/openrisc/mm/cache.c:25:3: note: in expansion of macro 'mtspr'
       25 |   mtspr(reg, line);
	  |   ^~~~~
    make[1]: *** [scripts/Makefile.build:283: arch/openrisc/mm/cache.o] Error 1

The asm constraint "K" requires a immediate constant argument to mtspr,
however because of no inlining a register argument is passed causing a
failure.  Fix this by using __always_inline.

Link: https://lore.kernel.org/lkml/202008200453.ohnhqkjQ%25lkp@intel.com/
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 arch/openrisc/mm/cache.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/openrisc/mm/cache.c b/arch/openrisc/mm/cache.c
index 08f56af387ac..534a52ec5e66 100644
--- a/arch/openrisc/mm/cache.c
+++ b/arch/openrisc/mm/cache.c
@@ -16,7 +16,7 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
-static void cache_loop(struct page *page, const unsigned int reg)
+static __always_inline void cache_loop(struct page *page, const unsigned int reg)
 {
 	unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT;
 	unsigned long line = paddr & ~(L1_CACHE_BYTES - 1);
-- 
2.26.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values
  2020-09-05 13:19 [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
  2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
  2020-09-05 13:19 ` [PATCH v2 2/3] openrisc: Fix cache API compile issue when not inlining Stafford Horne
@ 2020-09-05 13:19 ` Stafford Horne
  2020-09-05 13:57   ` Luc Van Oostenryck
  2020-09-05 13:24 ` [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
  3 siblings, 1 reply; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:19 UTC (permalink / raw)
  To: LKML
  Cc: Stafford Horne, Jonas Bonn, Stefan Kristiansson,
	Luc Van Oostenryck, Andrew Morton, Geert Uytterhoeven,
	Greentime Hu, openrisc

A build failure was raised by kbuild with the following error.

    drivers/android/binder.c: Assembler messages:
    drivers/android/binder.c:3861: Error: unrecognized keyword/register name `l.lwz ?ap,4(r24)'
    drivers/android/binder.c:3866: Error: unrecognized keyword/register name `l.addi ?ap,r0,0'

The issue is with 64-bit get_user() calls on openrisc.  I traced this to
a problem where in the internally in the get_user macros there is a cast
to long __gu_val this causes GCC to think the get_user call is 32-bit.
This binder code is really long and GCC allocates register r30, which
triggers the issue. The 64-bit get_user asm tries to get the 64-bit pair
register, which for r30 overflows the general register names and returns
the dummy register ?ap.

The fix is to just remove the assignment to the 32-bit temporary
variable __gu_val.

Link: https://lore.kernel.org/lkml/202008200453.ohnhqkjQ%25lkp@intel.com/
Signed-off-by: Stafford Horne <shorne@gmail.com>
---
 arch/openrisc/include/asm/uaccess.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index f0390211236b..4a8976dda1a5 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -165,19 +165,19 @@ struct __large_struct {
 
 #define __get_user_nocheck(x, ptr, size)			\
 ({								\
-	long __gu_err, __gu_val;				\
-	__get_user_size(__gu_val, (ptr), (size), __gu_err);	\
-	(x) = (__force __typeof__(*(ptr)))__gu_val;		\
+	long __gu_err;						\
+	__get_user_size((x), (ptr), (size), __gu_err);		\
 	__gu_err;						\
 })
 
 #define __get_user_check(x, ptr, size)					\
 ({									\
-	long __gu_err = -EFAULT, __gu_val = 0;				\
+	long __gu_err = -EFAULT;					\
 	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
-	if (access_ok(__gu_addr, size))			\
-		__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
-	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
+	if (access_ok(__gu_addr, size))					\
+		__get_user_size((x), __gu_addr, (size), __gu_err);	\
+	else								\
+		(x) = 0;						\
 	__gu_err;							\
 })
 
@@ -191,7 +191,7 @@ do {									\
 	case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break;		\
 	case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break;		\
 	case 8: __get_user_asm2(x, ptr, retval); break;			\
-	default: (x) = __get_user_bad();				\
+	default: (x) = (__typeof__(x)) __get_user_bad();		\
 	}								\
 } while (0)
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 0/3] OpenRISC fixes for 5.9
  2020-09-05 13:19 [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
                   ` (2 preceding siblings ...)
  2020-09-05 13:19 ` [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values Stafford Horne
@ 2020-09-05 13:24 ` Stafford Horne
  3 siblings, 0 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:24 UTC (permalink / raw)
  To: LKML

On Sat, Sep 05, 2020 at 10:19:32PM +0900, Stafford Horne wrote:
> Changes since v1:
> 
>  - Now a series, v1 was only the "Reserve memblock for initrd" patch
>  - Added fixes for compiler issues pointed out by the kbuild robot
Forgot to mention:
  - Updated "Reserve memblock for initrd", as per Mike's comments

> This is a few fixes found during testing 5.9.
> 
> Stafford Horne (3):
>   openrisc: Reserve memblock for initrd
>   openrisc: Fix cache API compile issue when not inlining
>   openrisc: Fix issue with get_user for 64-bit values
> 
>  arch/openrisc/include/asm/uaccess.h | 16 ++++++++--------
>  arch/openrisc/kernel/setup.c        | 10 ++++++++++
>  arch/openrisc/mm/cache.c            |  2 +-
>  3 files changed, 19 insertions(+), 9 deletions(-)
> 
> -- 
> 2.26.2
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/3] openrisc: Reserve memblock for initrd
  2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
@ 2020-09-05 13:25   ` Stafford Horne
  2020-09-06  6:15   ` Mike Rapoport
  1 sibling, 0 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 13:25 UTC (permalink / raw)
  To: LKML
  Cc: Jonas Bonn, Stefan Kristiansson, Mike Rapoport, Arvind Sankar,
	Greg Kroah-Hartman, Andrew Morton, openrisc

On Sat, Sep 05, 2020 at 10:19:33PM +0900, Stafford Horne wrote:
> Recently OpenRISC added support for external initrd images, but I found
> some instability when using larger buildroot initrd images. It turned
> out that I forgot to reserve the memblock space for the initrd image.
> 
> This patch fixes the instability issue by reserving memblock space.
> 
> Fixes: ff6c923dbec3 ("openrisc: Add support for external initrd images")
> Signed-off-by: Stafford Horne <shorne@gmail.com>
> ---
Forgot to mention:

Changes since v1:
  - Updated to use separate variables as suggested by Mike.

>  arch/openrisc/kernel/setup.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
> index b18e775f8be3..13c87f1f872b 100644
> --- a/arch/openrisc/kernel/setup.c
> +++ b/arch/openrisc/kernel/setup.c
> @@ -80,6 +80,16 @@ static void __init setup_memory(void)
>  	 */
>  	memblock_reserve(__pa(_stext), _end - _stext);
>  
> +#ifdef CONFIG_BLK_DEV_INITRD
> +	/* Then reserve the initrd, if any */
> +	if (initrd_start && (initrd_end > initrd_start)) {
> +		unsigned long aligned_start = ALIGN_DOWN(initrd_start, PAGE_SIZE);
> +		unsigned long aligned_end = ALIGN(initrd_end, PAGE_SIZE);
> +
> +		memblock_reserve(__pa(aligned_start), aligned_end - aligned_start);
> +	}
> +#endif /* CONFIG_BLK_DEV_INITRD */
> +
>  	early_init_fdt_reserve_self();
>  	early_init_fdt_scan_reserved_mem();
>  
> -- 
> 2.26.2
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values
  2020-09-05 13:19 ` [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values Stafford Horne
@ 2020-09-05 13:57   ` Luc Van Oostenryck
  2020-09-05 21:34     ` Stafford Horne
  0 siblings, 1 reply; 11+ messages in thread
From: Luc Van Oostenryck @ 2020-09-05 13:57 UTC (permalink / raw)
  To: Stafford Horne
  Cc: LKML, Jonas Bonn, Stefan Kristiansson, Andrew Morton,
	Geert Uytterhoeven, Greentime Hu, openrisc

On Sat, Sep 05, 2020 at 10:19:35PM +0900, Stafford Horne wrote:

Hi,

The change for 64-bit get_user() looks good to me.
But I wonder, given that openrisc is big-endian, what will happen
you have the opposite situation:
	u32 *ptr;
	u64 val;
	...
	get_user(val, ptr);

Won't you end with the value in the most significant part of
the register pair?

-- Luc

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values
  2020-09-05 13:57   ` Luc Van Oostenryck
@ 2020-09-05 21:34     ` Stafford Horne
  2020-09-06  0:22       ` [OpenRISC] " Luc Van Oostenryck
  0 siblings, 1 reply; 11+ messages in thread
From: Stafford Horne @ 2020-09-05 21:34 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: LKML, Jonas Bonn, Stefan Kristiansson, Andrew Morton,
	Geert Uytterhoeven, Greentime Hu, openrisc

On Sat, Sep 05, 2020 at 03:57:14PM +0200, Luc Van Oostenryck wrote:
> On Sat, Sep 05, 2020 at 10:19:35PM +0900, Stafford Horne wrote:
> 
> Hi,
> 
> The change for 64-bit get_user() looks good to me.
> But I wonder, given that openrisc is big-endian, what will happen
> you have the opposite situation:
> 	u32 *ptr;
> 	u64 val;
> 	...
> 	get_user(val, ptr);
> 
> Won't you end with the value in the most significant part of
> the register pair?

Hi Luc,

The get_user function uses the size of the ptr to determine how to do the load ,
so this case would not use the 64-bit pair register logic.  I think it should be
ok, the end result would be the same as c code:

  var = *ptr;

-Stafford

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [OpenRISC] [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values
  2020-09-05 21:34     ` Stafford Horne
@ 2020-09-06  0:22       ` Luc Van Oostenryck
  2020-09-06 21:00         ` Stafford Horne
  0 siblings, 1 reply; 11+ messages in thread
From: Luc Van Oostenryck @ 2020-09-06  0:22 UTC (permalink / raw)
  To: Stafford Horne; +Cc: Jonas Bonn, LKML, openrisc, Greentime Hu, Andrew Morton

On Sun, Sep 06, 2020 at 06:34:08AM +0900, Stafford Horne wrote:
> On Sat, Sep 05, 2020 at 03:57:14PM +0200, Luc Van Oostenryck wrote:
> > On Sat, Sep 05, 2020 at 10:19:35PM +0900, Stafford Horne wrote:
> > 
> > Hi,
> > 
> > The change for 64-bit get_user() looks good to me.
> > But I wonder, given that openrisc is big-endian, what will happen
> > you have the opposite situation:
> > 	u32 *ptr;
> > 	u64 val;
> > 	...
> > 	get_user(val, ptr);
> > 
> > Won't you end with the value in the most significant part of
> > the register pair?
> 
> Hi Luc,
> 
> The get_user function uses the size of the ptr to determine how to do the load ,
> so this case would not use the 64-bit pair register logic.  I think it should be
> ok, the end result would be the same as c code:
> 
>   var = *ptr;

Hi,

Sorry to insist but both won't give the same result.
The problem comes from the output part of the asm: "=r" (x).

The following code:
	u32 getp(u32 *ptr)
	{
		u64 val;
		val = *ptr;
		return val;
	}
will compile to something like:
	getp:
		l.jr	r9
		l.lwz	r11, 0(r3)

The load is written to r11, which is what is returned. OK.

But the get_user() code with a u32 pointer *and* a u64 destination
is equivalent to something like:
	u32 getl(u32 *ptr)
	{
		u64 val;

		asm("l.lwz %0,0(%1)" : "=r"(val) : "r"(ptr));
		return val;
	}
and this compiles to:
	getl:
		l.lwz	r17,0(r3)
		l.jr	r9
		l.or	r11, r19, r19

The load is written to r17 but what is returned is the content of r19.
Not good.

I think that, in the get_user() code:
* if the pointer is a pointer to a 64-bit quantity, then variable
  used in as the output in the asm needs to be a 64-bit variable
* if the pointer is a pointer to a 32-bit quantity, then variable
  used in as the output in the asm needs to be a 64-bit variable
At least one way to guarantee this is to use a temporary variable
that matches the size of the pointer.

-- Luc

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 1/3] openrisc: Reserve memblock for initrd
  2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
  2020-09-05 13:25   ` Stafford Horne
@ 2020-09-06  6:15   ` Mike Rapoport
  1 sibling, 0 replies; 11+ messages in thread
From: Mike Rapoport @ 2020-09-06  6:15 UTC (permalink / raw)
  To: Stafford Horne
  Cc: LKML, Jonas Bonn, Stefan Kristiansson, Arvind Sankar,
	Greg Kroah-Hartman, Andrew Morton, openrisc

On Sat, Sep 05, 2020 at 10:19:33PM +0900, Stafford Horne wrote:
> Recently OpenRISC added support for external initrd images, but I found
> some instability when using larger buildroot initrd images. It turned
> out that I forgot to reserve the memblock space for the initrd image.
> 
> This patch fixes the instability issue by reserving memblock space.
> 
> Fixes: ff6c923dbec3 ("openrisc: Add support for external initrd images")
> Signed-off-by: Stafford Horne <shorne@gmail.com>

Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>

> ---
>  arch/openrisc/kernel/setup.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
> index b18e775f8be3..13c87f1f872b 100644
> --- a/arch/openrisc/kernel/setup.c
> +++ b/arch/openrisc/kernel/setup.c
> @@ -80,6 +80,16 @@ static void __init setup_memory(void)
>  	 */
>  	memblock_reserve(__pa(_stext), _end - _stext);
>  
> +#ifdef CONFIG_BLK_DEV_INITRD
> +	/* Then reserve the initrd, if any */
> +	if (initrd_start && (initrd_end > initrd_start)) {
> +		unsigned long aligned_start = ALIGN_DOWN(initrd_start, PAGE_SIZE);
> +		unsigned long aligned_end = ALIGN(initrd_end, PAGE_SIZE);
> +
> +		memblock_reserve(__pa(aligned_start), aligned_end - aligned_start);
> +	}
> +#endif /* CONFIG_BLK_DEV_INITRD */
> +
>  	early_init_fdt_reserve_self();
>  	early_init_fdt_scan_reserved_mem();
>  
> -- 
> 2.26.2
> 

-- 
Sincerely yours,
Mike.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [OpenRISC] [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values
  2020-09-06  0:22       ` [OpenRISC] " Luc Van Oostenryck
@ 2020-09-06 21:00         ` Stafford Horne
  0 siblings, 0 replies; 11+ messages in thread
From: Stafford Horne @ 2020-09-06 21:00 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Jonas Bonn, LKML, openrisc, Greentime Hu, Andrew Morton

On Sun, Sep 06, 2020 at 02:22:28AM +0200, Luc Van Oostenryck wrote:
> On Sun, Sep 06, 2020 at 06:34:08AM +0900, Stafford Horne wrote:
> > On Sat, Sep 05, 2020 at 03:57:14PM +0200, Luc Van Oostenryck wrote:
> > > On Sat, Sep 05, 2020 at 10:19:35PM +0900, Stafford Horne wrote:
> > > 
> > > Hi,
> > > 
> > > The change for 64-bit get_user() looks good to me.
> > > But I wonder, given that openrisc is big-endian, what will happen
> > > you have the opposite situation:
> > > 	u32 *ptr;
> > > 	u64 val;
> > > 	...
> > > 	get_user(val, ptr);
> > > 
> > > Won't you end with the value in the most significant part of
> > > the register pair?
> > 
> > Hi Luc,
> > 
> > The get_user function uses the size of the ptr to determine how to do the load ,
> > so this case would not use the 64-bit pair register logic.  I think it should be
> > ok, the end result would be the same as c code:
> > 
> >   var = *ptr;
> 
> Hi,
> 
> Sorry to insist but both won't give the same result.
> The problem comes from the output part of the asm: "=r" (x).
> 
> The following code:
> 	u32 getp(u32 *ptr)
> 	{
> 		u64 val;
> 		val = *ptr;
> 		return val;
> 	}
> will compile to something like:
> 	getp:
> 		l.jr	r9
> 		l.lwz	r11, 0(r3)
> 
> The load is written to r11, which is what is returned. OK.
> 
> But the get_user() code with a u32 pointer *and* a u64 destination
> is equivalent to something like:
> 	u32 getl(u32 *ptr)
> 	{
> 		u64 val;
> 
> 		asm("l.lwz %0,0(%1)" : "=r"(val) : "r"(ptr));
> 		return val;
> 	}
> and this compiles to:
> 	getl:
> 		l.lwz	r17,0(r3)
> 		l.jr	r9
> 		l.or	r11, r19, r19
> 
> The load is written to r17 but what is returned is the content of r19.
> Not good.
> 
> I think that, in the get_user() code:
> * if the pointer is a pointer to a 64-bit quantity, then variable
>   used in as the output in the asm needs to be a 64-bit variable
> * if the pointer is a pointer to a 32-bit quantity, then variable
>   used in as the output in the asm needs to be a 64-bit variable
> At least one way to guarantee this is to use a temporary variable
> that matches the size of the pointer.

Hello,

Thanks for taking the time to explain.  I see your point, it makes sense I will
fix this up.

-Stafford

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-09-06 21:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-05 13:19 [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne
2020-09-05 13:19 ` [PATCH v2 1/3] openrisc: Reserve memblock for initrd Stafford Horne
2020-09-05 13:25   ` Stafford Horne
2020-09-06  6:15   ` Mike Rapoport
2020-09-05 13:19 ` [PATCH v2 2/3] openrisc: Fix cache API compile issue when not inlining Stafford Horne
2020-09-05 13:19 ` [PATCH v2 3/3] openrisc: Fix issue with get_user for 64-bit values Stafford Horne
2020-09-05 13:57   ` Luc Van Oostenryck
2020-09-05 21:34     ` Stafford Horne
2020-09-06  0:22       ` [OpenRISC] " Luc Van Oostenryck
2020-09-06 21:00         ` Stafford Horne
2020-09-05 13:24 ` [PATCH v2 0/3] OpenRISC fixes for 5.9 Stafford Horne

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).