Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2021-01-13 Thread Borislav Petkov
On Tue, Jan 12, 2021 at 08:34:46PM +0900, Masami Hiramatsu wrote:
> Or, add one definition before that line.
> 
> #define INSN_MODE_KERN -1 /* __ignore_sync_check__ */

I like that idea, thanks! And it seems to work:

---

diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 4cf2ad521f65..b56c5741581a 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include 
+#include  /* __ignore_sync_check__ */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 9f1910284861..6df0d3da0d86 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include 
+#include  /* __ignore_sync_check__ */
 
 struct insn_field {
union {
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
index 12539fca75c4..b0f3b2a62ae2 100644
--- a/arch/x86/lib/inat.c
+++ b/arch/x86/lib/inat.c
@@ -4,7 +4,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include 
+#include  /* __ignore_sync_check__ */
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 2ab1d0256313..aa6ee796a987 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -10,13 +10,13 @@
 #else
 #include 
 #endif
-#include 
-#include 
+#include  /*__ignore_sync_check__ */
+#include  /* __ignore_sync_check__ */
 
 #include 
 #include 
 
-#include 
+#include  /* __ignore_sync_check__ */
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)  \
@@ -748,6 +748,8 @@ int insn_decode(struct insn *insn, const void *kaddr, int 
buf_len, enum insn_mod
 {
int ret;
 
+/* #define INSN_MODE_KERN  -1 __ignore_sync_check__ mode is only valid in 
the kernel */
+
if (m == INSN_MODE_KERN)
insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
else
diff --git a/tools/arch/x86/include/asm/inat.h 
b/tools/arch/x86/include/asm/inat.h
index 877827b7c2c3..a61051400311 100644
--- a/tools/arch/x86/include/asm/inat.h
+++ b/tools/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include "inat_types.h"
+#include "inat_types.h" /* __ignore_sync_check__ */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/tools/arch/x86/include/asm/insn.h 
b/tools/arch/x86/include/asm/insn.h
index f8772b371452..4f219e3ae817 100644
--- a/tools/arch/x86/include/asm/insn.h
+++ b/tools/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include "inat.h"
+#include "inat.h" /* __ignore_sync_check__ */
 
 struct insn_field {
union {
diff --git a/tools/arch/x86/lib/inat.c b/tools/arch/x86/lib/inat.c
index 4f5ed49e1b4e..dfbcc6405941 100644
--- a/tools/arch/x86/lib/inat.c
+++ b/tools/arch/x86/lib/inat.c
@@ -4,7 +4,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include "../include/asm/insn.h"
+#include "../include/asm/insn.h" /* __ignore_sync_check__ */
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c
index c224e1569034..13e8615edc15 100644
--- a/tools/arch/x86/lib/insn.c
+++ b/tools/arch/x86/lib/insn.c
@@ -10,13 +10,13 @@
 #else
 #include 
 #endif
-#include "../include/asm/inat.h"
-#include "../include/asm/insn.h"
+#include "../include/asm/inat.h" /* __ignore_sync_check__ */
+#include "../include/asm/insn.h" /* __ignore_sync_check__ */
 
 #include 
 #include 
 
-#include "../include/asm/emulate_prefix.h"
+#include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)  \
@@ -748,6 +748,8 @@ int insn_decode(struct insn *insn, const void *kaddr, int 
buf_len, enum insn_mod
 {
int ret;
 
+#define INSN_MODE_KERN -1 /* __ignore_sync_check__ mode is only valid in the 
kernel */
+
if (m == INSN_MODE_KERN)
insn_init(insn, kaddr, buf_len, IS_ENABLED(CONFIG_X86_64));
else
diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh
index 606a4b5e929f..4bbabaecab14 100755
--- a/tools/objtool/sync-check.sh
+++ b/tools/objtool/sync-check.sh
@@ -16,11 +16,14 @@ arch/x86/include/asm/emulate_prefix.h
 arch/x86/lib/x86-opcode-map.txt
 arch/x86/tools/gen-insn-attr-x86.awk
 include/linux/static_call_types.h
-arch/x86/include/asm/inat.h -I '^#include [\"<]\(asm/\)*inat_types.h[\">]'
-arch/x86/include/asm/insn.h -I '^#include [\"<]\(asm/\)*inat.h[\">]'
-arch/x86/lib/inat.c -I '^#include 
[\"<]\(../include/\)*asm/insn.h[\">]'
-arch/x86/lib/insn.c -I '^#include 
[\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]' -I '^#include 

Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2021-01-12 Thread Masami Hiramatsu
On Fri, 8 Jan 2021 19:59:50 +0100
Borislav Petkov  wrote:

> On Wed, Jan 06, 2021 at 02:21:14PM +0900, Masami Hiramatsu wrote:
> > So I think it is possible to introduce a keyword in a comment
> > for ignoring sync check something like below. This will allow us
> > a generic pattern matching.
> > 
> > The keyword is just an example, "no-sync-check" etc. is OK.
> > 
> > What would you think about it?
> 
> Yeah, I'd prefer a single keyword which to slap everywhere, see below.
> The patch is only for demonstration, though, it is not complete.

Yes, that looks good to me too.

> 
> And while playing with that after having commented out INSN_MODE_KERN in
> the tools/ version, I realized that the build would always fail because
> insn.c references it:
> 
> In file included from arch/x86/decode.c:12:
> arch/x86/../../../arch/x86/lib/insn.c: In function ‘insn_decode’:
> arch/x86/../../../arch/x86/lib/insn.c:751:11: error: ‘INSN_MODE_KERN’ 
> undeclared (first use in this function); did you mean ‘INSN_MODE_64’?
>   751 |  if (m == INSN_MODE_KERN)
>   |   ^~
>   |   INSN_MODE_64
> 
> and making that work would turn pretty ugly because I wanna avoid
> slapping that __ignore_sync_check__ or whatever on more than one line.
> 
> So I need to think about a better solution here... 

Hmm, instead of removing INSN_MODE_KERN, if you just return an error,
it will change one line.

if (m == INSN_MODE_KERN)
return -EINVAL; /* __ignore_sync_check__ */
else
insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);

Or, add one definition before that line.

#define INSN_MODE_KERN -1   /* __ignore_sync_check__ */

Thank you,


> 
> ---
> diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
> index 4cf2ad521f65..b56c5741581a 100644
> --- a/arch/x86/include/asm/inat.h
> +++ b/arch/x86/include/asm/inat.h
> @@ -6,7 +6,7 @@
>   *
>   * Written by Masami Hiramatsu 
>   */
> -#include 
> +#include  /* __ignore_sync_check__ */
>  
>  /*
>   * Internal bits. Don't use bitmasks directly, because these bits are
> diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
> index 9f1910284861..601eac7a4973 100644
> --- a/arch/x86/include/asm/insn.h
> +++ b/arch/x86/include/asm/insn.h
> @@ -8,7 +8,7 @@
>   */
>  
>  /* insn_attr_t is defined in inat.h */
> -#include 
> +#include  /* __ignore_sync_check__ */
>  
>  struct insn_field {
>   union {
> @@ -99,7 +99,7 @@ enum insn_mode {
>   INSN_MODE_32,
>   INSN_MODE_64,
>   /* Mode is determined by the current kernel build. */
> - INSN_MODE_KERN,
> + INSN_MODE_KERN, /* __ignore_sync_check__ */
>   INSN_NUM_MODES,
>  };
>  
> diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
> index 12539fca75c4..b0f3b2a62ae2 100644
> --- a/arch/x86/lib/inat.c
> +++ b/arch/x86/lib/inat.c
> @@ -4,7 +4,7 @@
>   *
>   * Written by Masami Hiramatsu 
>   */
> -#include 
> +#include  /* __ignore_sync_check__ */
>  
>  /* Attribute tables are generated from opcode map */
>  #include "inat-tables.c"
> diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
> index 2ab1d0256313..1295003fb4f7 100644
> --- a/arch/x86/lib/insn.c
> +++ b/arch/x86/lib/insn.c
> @@ -10,13 +10,13 @@
>  #else
>  #include 
>  #endif
> -#include 
> -#include 
> +#include  /*__ignore_sync_check__ */
> +#include  /* __ignore_sync_check__ */
>  
>  #include 
>  #include 
>  
> -#include 
> +#include  /* __ignore_sync_check__ */
>  
>  /* Verify next sizeof(t) bytes can be on the same instruction */
>  #define validate_next(t, insn, n)\
> diff --git a/tools/arch/x86/include/asm/inat.h 
> b/tools/arch/x86/include/asm/inat.h
> index 877827b7c2c3..a61051400311 100644
> --- a/tools/arch/x86/include/asm/inat.h
> +++ b/tools/arch/x86/include/asm/inat.h
> @@ -6,7 +6,7 @@
>   *
>   * Written by Masami Hiramatsu 
>   */
> -#include "inat_types.h"
> +#include "inat_types.h" /* __ignore_sync_check__ */
>  
>  /*
>   * Internal bits. Don't use bitmasks directly, because these bits are
> diff --git a/tools/arch/x86/include/asm/insn.h 
> b/tools/arch/x86/include/asm/insn.h
> index f8772b371452..b12329de4e6e 100644
> --- a/tools/arch/x86/include/asm/insn.h
> +++ b/tools/arch/x86/include/asm/insn.h
> @@ -8,7 +8,7 @@
>   */
>  
>  /* insn_attr_t is defined in inat.h */
> -#include "inat.h"
> +#include "inat.h" /* __ignore_sync_check__ */
>  
>  struct insn_field {
>   union {
> @@ -99,7 +99,7 @@ enum insn_mode {
>   INSN_MODE_32,
>   INSN_MODE_64,
>   /* Mode is determined by the current kernel build. */
> - INSN_MODE_KERN,
> + /* INSN_MODE_KERN, __ignore_sync_check__ */
>   INSN_NUM_MODES,
>  };
>  
> diff --git a/tools/arch/x86/lib/inat.c b/tools/arch/x86/lib/inat.c
> index 4f5ed49e1b4e..dfbcc6405941 100644
> --- a/tools/arch/x86/lib/inat.c
> +++ b/tools/arch/x86/lib/inat.c
> @@ -4,7 +4,7 @@
>   *
>   * Written by Masami Hiramatsu 
>   */
> -#include "../include/asm/insn.h"
> +#include 

Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2021-01-08 Thread Borislav Petkov
On Wed, Jan 06, 2021 at 02:21:14PM +0900, Masami Hiramatsu wrote:
> So I think it is possible to introduce a keyword in a comment
> for ignoring sync check something like below. This will allow us
> a generic pattern matching.
> 
> The keyword is just an example, "no-sync-check" etc. is OK.
> 
> What would you think about it?

Yeah, I'd prefer a single keyword which to slap everywhere, see below.
The patch is only for demonstration, though, it is not complete.

And while playing with that after having commented out INSN_MODE_KERN in
the tools/ version, I realized that the build would always fail because
insn.c references it:

In file included from arch/x86/decode.c:12:
arch/x86/../../../arch/x86/lib/insn.c: In function ‘insn_decode’:
arch/x86/../../../arch/x86/lib/insn.c:751:11: error: ‘INSN_MODE_KERN’ 
undeclared (first use in this function); did you mean ‘INSN_MODE_64’?
  751 |  if (m == INSN_MODE_KERN)
  |   ^~
  |   INSN_MODE_64

and making that work would turn pretty ugly because I wanna avoid
slapping that __ignore_sync_check__ or whatever on more than one line.

So I need to think about a better solution here... 

---
diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 4cf2ad521f65..b56c5741581a 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include 
+#include  /* __ignore_sync_check__ */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 9f1910284861..601eac7a4973 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include 
+#include  /* __ignore_sync_check__ */
 
 struct insn_field {
union {
@@ -99,7 +99,7 @@ enum insn_mode {
INSN_MODE_32,
INSN_MODE_64,
/* Mode is determined by the current kernel build. */
-   INSN_MODE_KERN,
+   INSN_MODE_KERN, /* __ignore_sync_check__ */
INSN_NUM_MODES,
 };
 
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
index 12539fca75c4..b0f3b2a62ae2 100644
--- a/arch/x86/lib/inat.c
+++ b/arch/x86/lib/inat.c
@@ -4,7 +4,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include 
+#include  /* __ignore_sync_check__ */
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 2ab1d0256313..1295003fb4f7 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -10,13 +10,13 @@
 #else
 #include 
 #endif
-#include 
-#include 
+#include  /*__ignore_sync_check__ */
+#include  /* __ignore_sync_check__ */
 
 #include 
 #include 
 
-#include 
+#include  /* __ignore_sync_check__ */
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)  \
diff --git a/tools/arch/x86/include/asm/inat.h 
b/tools/arch/x86/include/asm/inat.h
index 877827b7c2c3..a61051400311 100644
--- a/tools/arch/x86/include/asm/inat.h
+++ b/tools/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include "inat_types.h"
+#include "inat_types.h" /* __ignore_sync_check__ */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/tools/arch/x86/include/asm/insn.h 
b/tools/arch/x86/include/asm/insn.h
index f8772b371452..b12329de4e6e 100644
--- a/tools/arch/x86/include/asm/insn.h
+++ b/tools/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include "inat.h"
+#include "inat.h" /* __ignore_sync_check__ */
 
 struct insn_field {
union {
@@ -99,7 +99,7 @@ enum insn_mode {
INSN_MODE_32,
INSN_MODE_64,
/* Mode is determined by the current kernel build. */
-   INSN_MODE_KERN,
+   /* INSN_MODE_KERN, __ignore_sync_check__ */
INSN_NUM_MODES,
 };
 
diff --git a/tools/arch/x86/lib/inat.c b/tools/arch/x86/lib/inat.c
index 4f5ed49e1b4e..dfbcc6405941 100644
--- a/tools/arch/x86/lib/inat.c
+++ b/tools/arch/x86/lib/inat.c
@@ -4,7 +4,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include "../include/asm/insn.h"
+#include "../include/asm/insn.h" /* __ignore_sync_check__ */
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c
index c224e1569034..0824ae531019 100644
--- a/tools/arch/x86/lib/insn.c
+++ b/tools/arch/x86/lib/insn.c
@@ -10,13 +10,13 @@
 #else
 #include 
 #endif
-#include "../include/asm/inat.h"
-#include "../include/asm/insn.h"
+#include "../include/asm/inat.h" /* __ignore_sync_check__ */
+#include "../include/asm/insn.h" /* __ignore_sync_check__ */
 
 #include 
 #include 
 
-#include "../include/asm/emulate_prefix.h"
+#include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 

Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2021-01-05 Thread Masami Hiramatsu
On Wed, 30 Dec 2020 10:28:33 +0100
Borislav Petkov  wrote:

> I still haven't thought about what do to exactly there wrt making
> sync-check.sh happy but the aspect of failing the build is a nice one.

So I think it is possible to introduce a keyword in a comment
for ignoring sync check something like below. This will allow us
a generic pattern matching.

The keyword is just an example, "no-sync-check" etc. is OK.

What would you think about it?

Thank you,

diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 4cf2ad521f65..ff3d119610f5 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include 
+#include /* Different from tools */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index a8c3d284fa46..dda4fe208659 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include 
+#include   /* Different from tools */
 
 struct insn_field {
union {
diff --git a/tools/arch/x86/include/asm/inat.h 
b/tools/arch/x86/include/asm/inat.h
index 877827b7c2c3..1fcfb4efb5f4 100644
--- a/tools/arch/x86/include/asm/inat.h
+++ b/tools/arch/x86/include/asm/inat.h
@@ -6,7 +6,7 @@
  *
  * Written by Masami Hiramatsu 
  */
-#include "inat_types.h"
+#include "inat_types.h"/* Different from kernel */
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/tools/arch/x86/include/asm/insn.h 
b/tools/arch/x86/include/asm/insn.h
index 52c6262e6bfd..702135ddb4fd 100644
--- a/tools/arch/x86/include/asm/insn.h
+++ b/tools/arch/x86/include/asm/insn.h
@@ -8,7 +8,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include "inat.h"
+#include "inat.h"  /* Different from kernel */
 
 struct insn_field {
union {
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh
index dded93a2bc89..b112d68c5513 100755
--- a/tools/perf/check-headers.sh
+++ b/tools/perf/check-headers.sh
@@ -137,8 +137,8 @@ check include/uapi/linux/mman.h   '-I "^#include 
<\(uapi/\)*asm/mman.h>"'
 check include/linux/build_bug.h   '-I "^#\(ifndef\|endif\)\( \/\/\)* 
static_assert$"'
 check include/linux/ctype.h  '-I "isdigit("'
 check lib/ctype.c'-I "^EXPORT_SYMBOL" -I "^#include 
" -B'
-check arch/x86/include/asm/inat.h '-I "^#include 
[\"<]\(asm/\)*inat_types.h[\">]"'
-check arch/x86/include/asm/insn.h '-I "^#include 
[\"<]\(asm/\)*inat.h[\">]"'
+check arch/x86/include/asm/inat.h '-I "^.*/\* Different from 
\(tools\|kernel\) \*/"'
+check arch/x86/include/asm/insn.h '-I "^.*/\* Different from 
\(tools\|kernel\) \*/"'
 check arch/x86/lib/inat.c'-I "^#include 
[\"<]\(../include/\)*asm/insn.h[\">]"'
 check arch/x86/lib/insn.c '-I "^#include 
[\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]" -I "^#include 
[\"<]\(../include/\)*asm/emulate_prefix.h[\">]"'
 
-- 
Masami Hiramatsu 


Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2020-12-30 Thread Borislav Petkov
On Wed, Dec 30, 2020 at 06:00:52PM +0900, Masami Hiramatsu wrote:
> Maybe I need to replace it with dummy lines but it is possible.

Dummy lines like "IGNORE DURING CHECK" or something like that?

> But in [17/19], your patch seems not using INSN_MODE_KERN there.

I replaced it only locally just so that I can cause the build error and
show you what mean.

I still haven't thought about what do to exactly there wrt making
sync-check.sh happy but the aspect of failing the build is a nice one.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette


Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2020-12-30 Thread Masami Hiramatsu
On Tue, 29 Dec 2020 21:06:54 +0100
Borislav Petkov  wrote:

> On Mon, Dec 28, 2020 at 10:15:10AM +0900, Masami Hiramatsu wrote:
> > BTW, insn_decode() can return -EINVAL if !insn_complete(), is that OK?
> 
> It does with this change. Or are you asking whether it returning -EINVAL
> in that case is ok?
> 
> I don't see why not - this way callers can differentiate where it failed
> - at fetching bytes with -ENODATA or it wasn't decoded completely -
> -EINVAL.

Ah, I got it.

> 
> > I think tools clone code must not use INSN_MODE_KERN because the tools may
> > not use kernel Kconfig.
> > 
> > Hmm, this may be better to make a different patch to introduce a NOSYNC tag
> > for sync checker in the tools. Something like;
> 
> I'd actually prefer this:
> 
> diff --git a/tools/arch/x86/include/asm/insn.h 
> b/tools/arch/x86/include/asm/insn.h
> index f8772b371452..545320c67855 100644
> --- a/tools/arch/x86/include/asm/insn.h
> +++ b/tools/arch/x86/include/asm/insn.h
> @@ -98,8 +98,6 @@ extern int insn_get_length(struct insn *insn);
>  enum insn_mode {
> INSN_MODE_32,
> INSN_MODE_64,
> -   /* Mode is determined by the current kernel build. */
> -   INSN_MODE_KERN,
> INSN_NUM_MODES,
>  };

Agreed. This is much simpler.
Maybe I need to replace it with dummy lines but it is possible.

>  
> 
> so that when a tool does use INSN_MODE_KERN, it would fail building:
> 
> In file included from util/intel-pt-decoder/intel-pt-insn-decoder.c:15:
> util/intel-pt-decoder/../../../arch/x86/lib/insn.c: In function ‘insn_decode’:
> util/intel-pt-decoder/../../../arch/x86/lib/insn.c:751:11: error: 
> ‘INSN_MODE_KERN’ undeclared (first use in this function); did you mean 
> ‘INSN_MODE_64’?
>   751 |  if (m == INSN_MODE_KERN)
>   |   ^~
>   |   INSN_MODE_64

This part is OK. I can replace it with dummy lines.

> util/intel-pt-decoder/../../../arch/x86/lib/insn.c:751:11: note: each 
> undeclared identifier is reported only once for each function it appears in
>   LD   arch/perf-in.o
> util/intel-pt-decoder/intel-pt-insn-decoder.c: In function 
> ‘intel_pt_get_insn’:
> util/intel-pt-decoder/intel-pt-insn-decoder.c:163:37: error: ‘INSN_MODE_KERN’ 
> undeclared (first use in this function); did you mean ‘INSN_MODE_64’?
>   163 |  ret = insn_decode(, buf, len, INSN_MODE_KERN);
>   | ^~
>   | INSN_MODE_64

But in [17/19], your patch seems not using INSN_MODE_KERN there.

--- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
@@ -158,11 +158,13 @@ int intel_pt_get_insn(const unsigned char *buf, size_t 
len, int x86_64,
  struct intel_pt_insn *intel_pt_insn)
 {
struct insn insn;
+   int ret;
 
-   insn_init(, buf, len, x86_64);
-   insn_get_length();
-   if (!insn_complete() || insn.length > len)
+   ret = insn_decode(, buf, len,
+ x86_64 ? INSN_MODE_64 : INSN_MODE_32);
+   if (ret < 0 || insn.length > len)
return -1;
+
intel_pt_insn_decoder(, intel_pt_insn);
if (insn.length < INTEL_PT_INSN_BUF_SZ)
memcpy(intel_pt_insn->buf, buf, insn.length);

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2020-12-29 Thread Borislav Petkov
On Mon, Dec 28, 2020 at 10:15:10AM +0900, Masami Hiramatsu wrote:
> BTW, insn_decode() can return -EINVAL if !insn_complete(), is that OK?

It does with this change. Or are you asking whether it returning -EINVAL
in that case is ok?

I don't see why not - this way callers can differentiate where it failed
- at fetching bytes with -ENODATA or it wasn't decoded completely -
-EINVAL.

> I think tools clone code must not use INSN_MODE_KERN because the tools may
> not use kernel Kconfig.
> 
> Hmm, this may be better to make a different patch to introduce a NOSYNC tag
> for sync checker in the tools. Something like;

I'd actually prefer this:

diff --git a/tools/arch/x86/include/asm/insn.h 
b/tools/arch/x86/include/asm/insn.h
index f8772b371452..545320c67855 100644
--- a/tools/arch/x86/include/asm/insn.h
+++ b/tools/arch/x86/include/asm/insn.h
@@ -98,8 +98,6 @@ extern int insn_get_length(struct insn *insn);
 enum insn_mode {
INSN_MODE_32,
INSN_MODE_64,
-   /* Mode is determined by the current kernel build. */
-   INSN_MODE_KERN,
INSN_NUM_MODES,
 };
 

so that when a tool does use INSN_MODE_KERN, it would fail building:

In file included from util/intel-pt-decoder/intel-pt-insn-decoder.c:15:
util/intel-pt-decoder/../../../arch/x86/lib/insn.c: In function ‘insn_decode’:
util/intel-pt-decoder/../../../arch/x86/lib/insn.c:751:11: error: 
‘INSN_MODE_KERN’ undeclared (first use in this function); did you mean 
‘INSN_MODE_64’?
  751 |  if (m == INSN_MODE_KERN)
  |   ^~
  |   INSN_MODE_64
util/intel-pt-decoder/../../../arch/x86/lib/insn.c:751:11: note: each 
undeclared identifier is reported only once for each function it appears in
  LD   arch/perf-in.o
util/intel-pt-decoder/intel-pt-insn-decoder.c: In function ‘intel_pt_get_insn’:
util/intel-pt-decoder/intel-pt-insn-decoder.c:163:37: error: ‘INSN_MODE_KERN’ 
undeclared (first use in this function); did you mean ‘INSN_MODE_64’?
  163 |  ret = insn_decode(, buf, len, INSN_MODE_KERN);
  | ^~
  | INSN_MODE_64

Thx.

-- 
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette


Re: [PATCH v1 03/19] x86/insn: Add an insn_decode() API

2020-12-27 Thread Masami Hiramatsu
Hi,

On Wed, 23 Dec 2020 18:42:17 +0100
Borislav Petkov  wrote:

> From: Borislav Petkov 
> 
> Users of the instruction decoder should use this to decode instruction
> bytes. For that, have insn*() helpers return an int value to denote
> success/failure. When there's an error fetching the next insn byte and
> the insn falls short, return -ENODATA to denote that.

-ENODATA sounds good to me :)

Acked-by: Masami Hiramatsu 

BTW, insn_decode() can return -EINVAL if !insn_complete(), is that OK?

> 
> While at it, make insn_get_opcode() more stricter as to whether what has
> seen so far is a valid insn and if not.
> 
> Copy linux/kconfig.h for the tools-version of the decoder so that it can
> use IS_ENABLED().

I think tools clone code must not use INSN_MODE_KERN because the tools may
not use kernel Kconfig.

Hmm, this may be better to make a different patch to introduce a NOSYNC tag
for sync checker in the tools. Something like;

> +int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum 
> insn_mode m)
> +{
> + int ret;
> +
> + if (m == INSN_MODE_KERN)
return -EINVAL; /* NOSYNC */
> + else
> + insn_init(insn, kaddr, buf_len, m == INSN_MODE_64);
> +

Then we can simple file list for sync-check.sh.

Thank you,

> 
> Signed-off-by: Borislav Petkov 
> ---
>  arch/x86/include/asm/insn.h   |  24 ++-
>  arch/x86/lib/insn.c   | 239 +++---
>  tools/arch/x86/include/asm/insn.h |  24 ++-
>  tools/arch/x86/lib/insn.c | 239 +++---
>  tools/include/linux/kconfig.h |  73 +
>  5 files changed, 475 insertions(+), 124 deletions(-)
>  create mode 100644 tools/include/linux/kconfig.h
> 
> diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
> index a8c3d284fa46..088aa90e9158 100644
> --- a/arch/x86/include/asm/insn.h
> +++ b/arch/x86/include/asm/insn.h
> @@ -87,13 +87,23 @@ struct insn {
>  #define X86_VEX_M_MAX0x1f/* VEX3.M Maximum value 
> */
>  
>  extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int 
> x86_64);
> -extern void insn_get_prefixes(struct insn *insn);
> -extern void insn_get_opcode(struct insn *insn);
> -extern void insn_get_modrm(struct insn *insn);
> -extern void insn_get_sib(struct insn *insn);
> -extern void insn_get_displacement(struct insn *insn);
> -extern void insn_get_immediate(struct insn *insn);
> -extern void insn_get_length(struct insn *insn);
> +extern int insn_get_prefixes(struct insn *insn);
> +extern int insn_get_opcode(struct insn *insn);
> +extern int insn_get_modrm(struct insn *insn);
> +extern int insn_get_sib(struct insn *insn);
> +extern int insn_get_displacement(struct insn *insn);
> +extern int insn_get_immediate(struct insn *insn);
> +extern int insn_get_length(struct insn *insn);
> +
> +enum insn_mode {
> + INSN_MODE_32,
> + INSN_MODE_64,
> + /* Mode is determined by the current kernel build. */
> + INSN_MODE_KERN,
> + INSN_NUM_MODES,
> +};
> +
> +extern int insn_decode(struct insn *insn, const void *kaddr, int buf_len, 
> enum insn_mode m);
>  
>  /* Attribute will be determined after getting ModRM (for opcode groups) */
>  static inline void insn_get_attribute(struct insn *insn)
> diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
> index 1ba994862b56..b373aadcdd02 100644
> --- a/arch/x86/lib/insn.c
> +++ b/arch/x86/lib/insn.c
> @@ -13,6 +13,9 @@
>  #include 
>  #include 
>  
> +#include 
> +#include 
> +
>  #include 
>  
>  /* Verify next sizeof(t) bytes can be on the same instruction */
> @@ -80,12 +83,15 @@ static int __insn_get_emulate_prefix(struct insn *insn,
>   return 1;
>  
>  err_out:
> - return 0;
> + return -ENODATA;
>  }
>  
>  static void insn_get_emulate_prefix(struct insn *insn)
>  {
> - if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
> + int ret;
> +
> + ret = __insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix));
> + if (ret > 0)
>   return;
>  
>   __insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
> @@ -98,8 +104,12 @@ static void insn_get_emulate_prefix(struct insn *insn)
>   * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
>   * to point to the (first) opcode.  No effect if @insn->prefixes.got
>   * is already set.
> + *
> + * * Returns:
> + * 0:  on success
> + * < 0: on error
>   */
> -void insn_get_prefixes(struct insn *insn)
> +int insn_get_prefixes(struct insn *insn)
>  {
>   struct insn_field *prefixes = >prefixes;
>   insn_attr_t attr;
> @@ -107,7 +117,7 @@ void insn_get_prefixes(struct insn *insn)
>   int i, nb;
>  
>   if (prefixes->got)
> - return;
> + return 0;
>  
>   insn_get_emulate_prefix(insn);
>  
> @@ -218,8 +228,10 @@ void insn_get_prefixes(struct insn *insn)
>  
>   prefixes->got = 1;
>  
> + return 0;
> +
>  err_out:
> - return;
> + return 

[PATCH v1 03/19] x86/insn: Add an insn_decode() API

2020-12-23 Thread Borislav Petkov
From: Borislav Petkov 

Users of the instruction decoder should use this to decode instruction
bytes. For that, have insn*() helpers return an int value to denote
success/failure. When there's an error fetching the next insn byte and
the insn falls short, return -ENODATA to denote that.

While at it, make insn_get_opcode() more stricter as to whether what has
seen so far is a valid insn and if not.

Copy linux/kconfig.h for the tools-version of the decoder so that it can
use IS_ENABLED().

Signed-off-by: Borislav Petkov 
---
 arch/x86/include/asm/insn.h   |  24 ++-
 arch/x86/lib/insn.c   | 239 +++---
 tools/arch/x86/include/asm/insn.h |  24 ++-
 tools/arch/x86/lib/insn.c | 239 +++---
 tools/include/linux/kconfig.h |  73 +
 5 files changed, 475 insertions(+), 124 deletions(-)
 create mode 100644 tools/include/linux/kconfig.h

diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index a8c3d284fa46..088aa90e9158 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -87,13 +87,23 @@ struct insn {
 #define X86_VEX_M_MAX  0x1f/* VEX3.M Maximum value */
 
 extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int 
x86_64);
-extern void insn_get_prefixes(struct insn *insn);
-extern void insn_get_opcode(struct insn *insn);
-extern void insn_get_modrm(struct insn *insn);
-extern void insn_get_sib(struct insn *insn);
-extern void insn_get_displacement(struct insn *insn);
-extern void insn_get_immediate(struct insn *insn);
-extern void insn_get_length(struct insn *insn);
+extern int insn_get_prefixes(struct insn *insn);
+extern int insn_get_opcode(struct insn *insn);
+extern int insn_get_modrm(struct insn *insn);
+extern int insn_get_sib(struct insn *insn);
+extern int insn_get_displacement(struct insn *insn);
+extern int insn_get_immediate(struct insn *insn);
+extern int insn_get_length(struct insn *insn);
+
+enum insn_mode {
+   INSN_MODE_32,
+   INSN_MODE_64,
+   /* Mode is determined by the current kernel build. */
+   INSN_MODE_KERN,
+   INSN_NUM_MODES,
+};
+
+extern int insn_decode(struct insn *insn, const void *kaddr, int buf_len, enum 
insn_mode m);
 
 /* Attribute will be determined after getting ModRM (for opcode groups) */
 static inline void insn_get_attribute(struct insn *insn)
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 1ba994862b56..b373aadcdd02 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -13,6 +13,9 @@
 #include 
 #include 
 
+#include 
+#include 
+
 #include 
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
@@ -80,12 +83,15 @@ static int __insn_get_emulate_prefix(struct insn *insn,
return 1;
 
 err_out:
-   return 0;
+   return -ENODATA;
 }
 
 static void insn_get_emulate_prefix(struct insn *insn)
 {
-   if (__insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix)))
+   int ret;
+
+   ret = __insn_get_emulate_prefix(insn, xen_prefix, sizeof(xen_prefix));
+   if (ret > 0)
return;
 
__insn_get_emulate_prefix(insn, kvm_prefix, sizeof(kvm_prefix));
@@ -98,8 +104,12 @@ static void insn_get_emulate_prefix(struct insn *insn)
  * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
  * to point to the (first) opcode.  No effect if @insn->prefixes.got
  * is already set.
+ *
+ * * Returns:
+ * 0:  on success
+ * < 0: on error
  */
-void insn_get_prefixes(struct insn *insn)
+int insn_get_prefixes(struct insn *insn)
 {
struct insn_field *prefixes = >prefixes;
insn_attr_t attr;
@@ -107,7 +117,7 @@ void insn_get_prefixes(struct insn *insn)
int i, nb;
 
if (prefixes->got)
-   return;
+   return 0;
 
insn_get_emulate_prefix(insn);
 
@@ -218,8 +228,10 @@ void insn_get_prefixes(struct insn *insn)
 
prefixes->got = 1;
 
+   return 0;
+
 err_out:
-   return;
+   return -ENODATA;
 }
 
 /**
@@ -231,16 +243,25 @@ void insn_get_prefixes(struct insn *insn)
  * If necessary, first collects any preceding (prefix) bytes.
  * Sets @insn->opcode.value = opcode1.  No effect if @insn->opcode.got
  * is already 1.
+ *
+ * Returns:
+ * 0:  on success
+ * < 0: on error
  */
-void insn_get_opcode(struct insn *insn)
+int insn_get_opcode(struct insn *insn)
 {
struct insn_field *opcode = >opcode;
+   int pfx_id, ret;
insn_byte_t op;
-   int pfx_id;
+
if (opcode->got)
-   return;
-   if (!insn->prefixes.got)
-   insn_get_prefixes(insn);
+   return 0;
+
+   if (!insn->prefixes.got) {
+   ret = insn_get_prefixes(insn);
+   if (ret)
+   return ret;
+   }
 
/* Get first opcode */
op = get_next(insn_byte_t, insn);
@@ -255,9 +276,13 @@ void insn_get_opcode(struct insn *insn)
insn->attr =