All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
@ 2017-06-28 14:55 Luc Van Oostenryck
  2017-06-29 10:28 ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Luc Van Oostenryck @ 2017-06-28 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

get_alt_insn() is used to read and create ARM instructions, which
are always stored in memory in little-endian order. These values
are thus correctly converted to/from native order when processed
but the pointers used to hold the address of these instructions
are declared as for native order values.

Fix this by declaring the pointers as __le32* instead of u32* and
make the few appropriate needed changes.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 arch/arm64/kernel/alternative.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 8840c109c..56bfda8cb 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -60,7 +60,7 @@ static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
 
 #define align_down(x, a)	((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
 
-static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
+static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr)
 {
 	u32 insn;
 
@@ -109,7 +109,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
 {
 	struct alt_instr *alt;
 	struct alt_region *region = alt_region;
-	u32 *origptr, *replptr, *updptr;
+	__le32 *origptr, *replptr, *updptr;
 
 	for (alt = region->begin; alt < region->end; alt++) {
 		u32 insn;
@@ -122,9 +122,9 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
 
 		pr_info_once("patching kernel code\n");
 
-		origptr = ALT_ORIG_PTR(alt);
-		replptr = ALT_REPL_PTR(alt);
-		updptr = use_linear_alias ? (u32 *)lm_alias(origptr) : origptr;
+		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
+		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
+		updptr = use_linear_alias ? (__le32 *)lm_alias(origptr) : origptr;
 		nr_inst = alt->alt_len / sizeof(insn);
 
 		for (i = 0; i < nr_inst; i++) {
-- 
2.13.0

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-28 14:55 [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn() Luc Van Oostenryck
@ 2017-06-29 10:28 ` Will Deacon
  2017-06-29 13:26   ` Luc Van Oostenryck
  0 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2017-06-29 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> get_alt_insn() is used to read and create ARM instructions, which
> are always stored in memory in little-endian order. These values
> are thus correctly converted to/from native order when processed
> but the pointers used to hold the address of these instructions
> are declared as for native order values.
> 
> Fix this by declaring the pointers as __le32* instead of u32* and
> make the few appropriate needed changes.
> 
> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
> ---
>  arch/arm64/kernel/alternative.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
> index 8840c109c..56bfda8cb 100644
> --- a/arch/arm64/kernel/alternative.c
> +++ b/arch/arm64/kernel/alternative.c
> @@ -60,7 +60,7 @@ static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
>  
>  #define align_down(x, a)	((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
>  
> -static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
> +static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr)
>  {
>  	u32 insn;
>  
> @@ -109,7 +109,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
>  {
>  	struct alt_instr *alt;
>  	struct alt_region *region = alt_region;
> -	u32 *origptr, *replptr, *updptr;
> +	__le32 *origptr, *replptr, *updptr;
>  
>  	for (alt = region->begin; alt < region->end; alt++) {
>  		u32 insn;
> @@ -122,9 +122,9 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
>  
>  		pr_info_once("patching kernel code\n");
>  
> -		origptr = ALT_ORIG_PTR(alt);
> -		replptr = ALT_REPL_PTR(alt);
> -		updptr = use_linear_alias ? (u32 *)lm_alias(origptr) : origptr;
> +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);

Why is the __force needed here?

Will

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 10:28 ` Will Deacon
@ 2017-06-29 13:26   ` Luc Van Oostenryck
  2017-06-29 14:11     ` Will Deacon
                       ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Luc Van Oostenryck @ 2017-06-29 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > get_alt_insn() is used to read and create ARM instructions, which
> > are always stored in memory in little-endian order. These values
> > are thus correctly converted to/from native order when processed
> > but the pointers used to hold the address of these instructions
> > are declared as for native order values.
> > 
> > Fix this by declaring the pointers as __le32* instead of u32* and
> > make the few appropriate needed changes.
> > 
> > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> 
> Why is the __force needed here?

Because of the cast to u32* in:
	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)

Of course, if this (u32*) is not really needed, then the __force
is also not needed.

And since, it seems indeed to be the case, I'll gladly sent a patch:
	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
if it suits you.

-- Luc

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 13:26   ` Luc Van Oostenryck
@ 2017-06-29 14:11     ` Will Deacon
  2017-06-29 14:13     ` Mark Rutland
  2017-06-29 14:40     ` [PATCH v2] " Luc Van Oostenryck
  2 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2017-06-29 14:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > > get_alt_insn() is used to read and create ARM instructions, which
> > > are always stored in memory in little-endian order. These values
> > > are thus correctly converted to/from native order when processed
> > > but the pointers used to hold the address of these instructions
> > > are declared as for native order values.
> > > 
> > > Fix this by declaring the pointers as __le32* instead of u32* and
> > > make the few appropriate needed changes.
> > > 
> > > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > 
> > Why is the __force needed here?
> 
> Because of the cast to u32* in:
> 	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> 	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> 	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> 
> Of course, if this (u32*) is not really needed, then the __force
> is also not needed.
> 
> And since, it seems indeed to be the case, I'll gladly sent a patch:
> 	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> 	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> if it suits you.

Yes, please!

Will

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 13:26   ` Luc Van Oostenryck
  2017-06-29 14:11     ` Will Deacon
@ 2017-06-29 14:13     ` Mark Rutland
  2017-06-29 14:19       ` Will Deacon
  2017-06-29 14:40     ` [PATCH v2] " Luc Van Oostenryck
  2 siblings, 1 reply; 12+ messages in thread
From: Mark Rutland @ 2017-06-29 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > > get_alt_insn() is used to read and create ARM instructions, which
> > > are always stored in memory in little-endian order. These values
> > > are thus correctly converted to/from native order when processed
> > > but the pointers used to hold the address of these instructions
> > > are declared as for native order values.
> > > 
> > > Fix this by declaring the pointers as __le32* instead of u32* and
> > > make the few appropriate needed changes.
> > > 
> > > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > 
> > Why is the __force needed here?
> 
> Because of the cast to u32* in:
> 	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> 	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> 	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> 
> Of course, if this (u32*) is not really needed, then the __force
> is also not needed.
> 
> And since, it seems indeed to be the case, I'll gladly sent a patch:
> 	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> 	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> if it suits you.

Given __ALT_PTR is intended to give a pointer to A64 instructions, which
are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
__le32 * ?

Thanks,
Mark.

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 14:13     ` Mark Rutland
@ 2017-06-29 14:19       ` Will Deacon
  2017-06-29 14:22         ` Mark Rutland
  0 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2017-06-29 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
> On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > > On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > > > get_alt_insn() is used to read and create ARM instructions, which
> > > > are always stored in memory in little-endian order. These values
> > > > are thus correctly converted to/from native order when processed
> > > > but the pointers used to hold the address of these instructions
> > > > are declared as for native order values.
> > > > 
> > > > Fix this by declaring the pointers as __le32* instead of u32* and
> > > > make the few appropriate needed changes.
> > > > 
> > > > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > > > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > > 
> > > Why is the __force needed here?
> > 
> > Because of the cast to u32* in:
> > 	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> > 	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> > 	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > 
> > Of course, if this (u32*) is not really needed, then the __force
> > is also not needed.
> > 
> > And since, it seems indeed to be the case, I'll gladly sent a patch:
> > 	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > 	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> > if it suits you.
> 
> Given __ALT_PTR is intended to give a pointer to A64 instructions, which
> are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
> __le32 * ?

Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.

Will

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 14:19       ` Will Deacon
@ 2017-06-29 14:22         ` Mark Rutland
  2017-06-29 14:26           ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Mark Rutland @ 2017-06-29 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 03:19:44PM +0100, Will Deacon wrote:
> On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
> > On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> > > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > > > On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > > > > get_alt_insn() is used to read and create ARM instructions, which
> > > > > are always stored in memory in little-endian order. These values
> > > > > are thus correctly converted to/from native order when processed
> > > > > but the pointers used to hold the address of these instructions
> > > > > are declared as for native order values.
> > > > > 
> > > > > Fix this by declaring the pointers as __le32* instead of u32* and
> > > > > make the few appropriate needed changes.
> > > > > 
> > > > > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > > > > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > > > 
> > > > Why is the __force needed here?
> > > 
> > > Because of the cast to u32* in:
> > > 	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> > > 	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> > > 	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > > 
> > > Of course, if this (u32*) is not really needed, then the __force
> > > is also not needed.
> > > 
> > > And since, it seems indeed to be the case, I'll gladly sent a patch:
> > > 	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > > 	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> > > if it suits you.
> > 
> > Given __ALT_PTR is intended to give a pointer to A64 instructions, which
> > are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
> > __le32 * ?
> 
> Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.

Maybe, but that's one cast, rather than two, and matches other similar
casts from a pointer to unsigned long (e.g. the the addr cast in
__range_ok()).

Thanks,
Mark.

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 14:22         ` Mark Rutland
@ 2017-06-29 14:26           ` Will Deacon
  2017-06-29 15:15             ` Luc Van Oostenryck
  0 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2017-06-29 14:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 03:22:34PM +0100, Mark Rutland wrote:
> On Thu, Jun 29, 2017 at 03:19:44PM +0100, Will Deacon wrote:
> > On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
> > > On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> > > > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > > > > On Wed, Jun 28, 2017 at 04:55:57PM +0200, Luc Van Oostenryck wrote:
> > > > > > get_alt_insn() is used to read and create ARM instructions, which
> > > > > > are always stored in memory in little-endian order. These values
> > > > > > are thus correctly converted to/from native order when processed
> > > > > > but the pointers used to hold the address of these instructions
> > > > > > are declared as for native order values.
> > > > > > 
> > > > > > Fix this by declaring the pointers as __le32* instead of u32* and
> > > > > > make the few appropriate needed changes.
> > > > > > 
> > > > > > +		origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > > > > > +		replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > > > > 
> > > > > Why is the __force needed here?
> > > > 
> > > > Because of the cast to u32* in:
> > > > 	#define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> > > > 	#define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> > > > 	#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > > > 
> > > > Of course, if this (u32*) is not really needed, then the __force
> > > > is also not needed.
> > > > 
> > > > And since, it seems indeed to be the case, I'll gladly sent a patch:
> > > > 	-#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > > > 	+#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> > > > if it suits you.
> > > 
> > > Given __ALT_PTR is intended to give a pointer to A64 instructions, which
> > > are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
> > > __le32 * ?
> > 
> > Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.
> 
> Maybe, but that's one cast, rather than two, and matches other similar
> casts from a pointer to unsigned long (e.g. the the addr cast in
> __range_ok()).

Sure, but isn't it a __force cast? I'd like to avoid that if we can.

Will

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

* [PATCH v2] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 13:26   ` Luc Van Oostenryck
  2017-06-29 14:11     ` Will Deacon
  2017-06-29 14:13     ` Mark Rutland
@ 2017-06-29 14:40     ` Luc Van Oostenryck
  2 siblings, 0 replies; 12+ messages in thread
From: Luc Van Oostenryck @ 2017-06-29 14:40 UTC (permalink / raw)
  To: linux-arm-kernel

get_alt_insn() is used to read and create ARM instructions, which
are always stored in memory in little-endian order. These values
are thus correctly converted to/from native order when processed
but the pointers used to hold the address of these instructions
are declared as for native order values.

Fix this by declaring the pointers as __le32* instead of u32* and
make the few appropriate needed changes like removing the unneeded
cast '(u32*)' in front of __ALT_PTR()'s definition.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>

---
Change since v1:
- remove the unneeded cast '(u32*)' in front of __ALT_PTR()'s definition.
- remove the now unneeded forced cast to __le32* when using
  ALT_ORIG_PTR() or ALT_REPL_PTR().
- remove an unnneded cast in front of lm_alias().

 arch/arm64/kernel/alternative.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 8840c109c..6dd0a3a3e 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -28,7 +28,7 @@
 #include <asm/sections.h>
 #include <linux/stop_machine.h>
 
-#define __ALT_PTR(a,f)		(u32 *)((void *)&(a)->f + (a)->f)
+#define __ALT_PTR(a,f)		((void *)&(a)->f + (a)->f)
 #define ALT_ORIG_PTR(a)		__ALT_PTR(a, orig_offset)
 #define ALT_REPL_PTR(a)		__ALT_PTR(a, alt_offset)
 
@@ -60,7 +60,7 @@ static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc)
 
 #define align_down(x, a)	((unsigned long)(x) & ~(((unsigned long)(a)) - 1))
 
-static u32 get_alt_insn(struct alt_instr *alt, u32 *insnptr, u32 *altinsnptr)
+static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr)
 {
 	u32 insn;
 
@@ -109,7 +109,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
 {
 	struct alt_instr *alt;
 	struct alt_region *region = alt_region;
-	u32 *origptr, *replptr, *updptr;
+	__le32 *origptr, *replptr, *updptr;
 
 	for (alt = region->begin; alt < region->end; alt++) {
 		u32 insn;
@@ -124,7 +124,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
 
 		origptr = ALT_ORIG_PTR(alt);
 		replptr = ALT_REPL_PTR(alt);
-		updptr = use_linear_alias ? (u32 *)lm_alias(origptr) : origptr;
+		updptr = use_linear_alias ? lm_alias(origptr) : origptr;
 		nr_inst = alt->alt_len / sizeof(insn);
 
 		for (i = 0; i < nr_inst; i++) {
-- 
2.13.0

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 14:26           ` Will Deacon
@ 2017-06-29 15:15             ` Luc Van Oostenryck
  2017-06-29 15:20               ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Luc Van Oostenryck @ 2017-06-29 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 4:26 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Thu, Jun 29, 2017 at 03:22:34PM +0100, Mark Rutland wrote:
>> On Thu, Jun 29, 2017 at 03:19:44PM +0100, Will Deacon wrote:
>> > On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
>> > > On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
>> > > > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
>> > > > > > +           origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
>> > > > > > +           replptr = (__le32 __force *) ALT_REPL_PTR(alt);
>> > > > >
>> > > > > Why is the __force needed here?
>> > > >
>> > > > Because of the cast to u32* in:
>> > > >         #define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
>> > > >         #define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
>> > > >         #define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
>> > > >
>> > > > Of course, if this (u32*) is not really needed, then the __force
>> > > > is also not needed.
>> > > >
>> > > > And since, it seems indeed to be the case, I'll gladly sent a patch:
>> > > >         -#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
>> > > >         +#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
>> > > > if it suits you.
>> > >
>> > > Given __ALT_PTR is intended to give a pointer to A64 instructions, which
>> > > are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
>> > > __le32 * ?

Yes, it could.

>> > Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.
>>
>> Maybe, but that's one cast, rather than two, and matches other similar
>> casts from a pointer to unsigned long (e.g. the the addr cast in
>> __range_ok()).
>
> Sure, but isn't it a __force cast? I'd like to avoid that if we can.

No, once you cast to an integer all the specificities of pointers are
thrown away,
like for a const pointer and here the __bitwise underlying the __le32.
It's exactly the same fro cast from/to void*, the reasoning behind it
is something
like : "it's OK to drop all the qualifiers and such because you will anyway need
to cast the result to another pointer before being able to dereference it".

I already sent a version leaving the type as void*, without having seen your
replies here, but if you wish I can, of course, resend something for __le32*.

-- Luc

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 15:15             ` Luc Van Oostenryck
@ 2017-06-29 15:20               ` Will Deacon
  2017-06-29 15:56                 ` Luc Van Oostenryck
  0 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2017-06-29 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 05:15:19PM +0200, Luc Van Oostenryck wrote:
> On Thu, Jun 29, 2017 at 4:26 PM, Will Deacon <will.deacon@arm.com> wrote:
> > On Thu, Jun 29, 2017 at 03:22:34PM +0100, Mark Rutland wrote:
> >> On Thu, Jun 29, 2017 at 03:19:44PM +0100, Will Deacon wrote:
> >> > On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
> >> > > On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> >> > > > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> >> > > > > > +           origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> >> > > > > > +           replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> >> > > > >
> >> > > > > Why is the __force needed here?
> >> > > >
> >> > > > Because of the cast to u32* in:
> >> > > >         #define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> >> > > >         #define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> >> > > >         #define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> >> > > >
> >> > > > Of course, if this (u32*) is not really needed, then the __force
> >> > > > is also not needed.
> >> > > >
> >> > > > And since, it seems indeed to be the case, I'll gladly sent a patch:
> >> > > >         -#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> >> > > >         +#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> >> > > > if it suits you.
> >> > >
> >> > > Given __ALT_PTR is intended to give a pointer to A64 instructions, which
> >> > > are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
> >> > > __le32 * ?
> 
> Yes, it could.
> 
> >> > Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.
> >>
> >> Maybe, but that's one cast, rather than two, and matches other similar
> >> casts from a pointer to unsigned long (e.g. the the addr cast in
> >> __range_ok()).
> >
> > Sure, but isn't it a __force cast? I'd like to avoid that if we can.
> 
> No, once you cast to an integer all the specificities of pointers are
> thrown away,
> like for a const pointer and here the __bitwise underlying the __le32.
> It's exactly the same fro cast from/to void*, the reasoning behind it
> is something
> like : "it's OK to drop all the qualifiers and such because you will anyway need
> to cast the result to another pointer before being able to dereference it".

Ok, so does that mean that the __force cast in __range_ok is not needed?

> I already sent a version leaving the type as void*, without having seen your
> replies here, but if you wish I can, of course, resend something for __le32*.

I'm happy with the patch you sent, so no need to resend.

Will

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

* [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn()
  2017-06-29 15:20               ` Will Deacon
@ 2017-06-29 15:56                 ` Luc Van Oostenryck
  0 siblings, 0 replies; 12+ messages in thread
From: Luc Van Oostenryck @ 2017-06-29 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 29, 2017 at 04:20:17PM +0100, Will Deacon wrote:
> On Thu, Jun 29, 2017 at 05:15:19PM +0200, Luc Van Oostenryck wrote:
> > On Thu, Jun 29, 2017 at 4:26 PM, Will Deacon <will.deacon@arm.com> wrote:
> > > On Thu, Jun 29, 2017 at 03:22:34PM +0100, Mark Rutland wrote:
> > >> On Thu, Jun 29, 2017 at 03:19:44PM +0100, Will Deacon wrote:
> > >> > On Thu, Jun 29, 2017 at 03:13:23PM +0100, Mark Rutland wrote:
> > >> > > On Thu, Jun 29, 2017 at 03:26:47PM +0200, Luc Van Oostenryck wrote:
> > >> > > > On Thu, Jun 29, 2017 at 11:28:51AM +0100, Will Deacon wrote:
> > >> > > > > > +           origptr = (__le32 __force *) ALT_ORIG_PTR(alt);
> > >> > > > > > +           replptr = (__le32 __force *) ALT_REPL_PTR(alt);
> > >> > > > >
> > >> > > > > Why is the __force needed here?
> > >> > > >
> > >> > > > Because of the cast to u32* in:
> > >> > > >         #define ALT_ORIG_PTR(a)         __ALT_PTR(a, orig_offset)
> > >> > > >         #define ALT_REPL_PTR(a)         __ALT_PTR(a, alt_offset)
> > >> > > >         #define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > >> > > >
> > >> > > > Of course, if this (u32*) is not really needed, then the __force
> > >> > > > is also not needed.
> > >> > > >
> > >> > > > And since, it seems indeed to be the case, I'll gladly sent a patch:
> > >> > > >         -#define __ALT_PTR(a,f)          (u32 *)((void *)&(a)->f + (a)->f)
> > >> > > >         +#define __ALT_PTR(a,f)          ((void *)&(a)->f + (a)->f)
> > >> > > > if it suits you.
> > >> > >
> > >> > > Given __ALT_PTR is intended to give a pointer to A64 instructions, which
> > >> > > are in le32 format, wouldn't it make more sense for __ALT_PTR to cast to
> > >> > > __le32 * ?
> > 
> > Yes, it could.
> > 
> > >> > Might be a bit weird for ALT_REPL_PTR, which is cast to unsigned long.
> > >>
> > >> Maybe, but that's one cast, rather than two, and matches other similar
> > >> casts from a pointer to unsigned long (e.g. the the addr cast in
> > >> __range_ok()).
> > >
> > > Sure, but isn't it a __force cast? I'd like to avoid that if we can.
> > 
> > No, once you cast to an integer all the specificities of pointers are
> > thrown away,
> > like for a const pointer and here the __bitwise underlying the __le32.
> > It's exactly the same fro cast from/to void*, the reasoning behind it
> > is something
> > like : "it's OK to drop all the qualifiers and such because you will anyway need
> > to cast the result to another pointer before being able to dereference it".
> 
> Ok, so does that mean that the __force cast in __range_ok is not needed?

Indeed. 

And I just verified this with a quick check with sparse only on arch/arm64/
with and without the __force.

> > I already sent a version leaving the type as void*, without having seen your
> > replies here, but if you wish I can, of course, resend something for __le32*.
> 
> I'm happy with the patch you sent, so no need to resend.

OK.

-- Luc 

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

end of thread, other threads:[~2017-06-29 15:56 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-28 14:55 [PATCH] arm64: fix endianness annotation for __apply_alternatives()/get_alt_insn() Luc Van Oostenryck
2017-06-29 10:28 ` Will Deacon
2017-06-29 13:26   ` Luc Van Oostenryck
2017-06-29 14:11     ` Will Deacon
2017-06-29 14:13     ` Mark Rutland
2017-06-29 14:19       ` Will Deacon
2017-06-29 14:22         ` Mark Rutland
2017-06-29 14:26           ` Will Deacon
2017-06-29 15:15             ` Luc Van Oostenryck
2017-06-29 15:20               ` Will Deacon
2017-06-29 15:56                 ` Luc Van Oostenryck
2017-06-29 14:40     ` [PATCH v2] " Luc Van Oostenryck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.