Skip to content

Commit 674d2d6

Browse files
author
Ingo Molnar
committed
Merge tag 'perf-core-for-mingo-20160725' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Add AVX-512 support to the instruction decoder, used by Intel PT, fix vcvtph2ps instruction decoding (Adrian Hunter) - Make objtool and vdso2c use the right arch header search path (Stephen Rothwell, Josh Poimboeuf, Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
2 parents 5048c2a + 4e3ba8a commit 674d2d6

File tree

19 files changed

+4221
-223
lines changed

19 files changed

+4221
-223
lines changed

arch/x86/entry/vdso/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
5555
$(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
5656
$(call if_changed,vdso)
5757

58-
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/x86/include/uapi
58+
HOST_EXTRACFLAGS += -I$(srctree)/tools/include -I$(srctree)/include/uapi -I$(srctree)/arch/$(SUBARCH)/include/uapi
5959
hostprogs-y += vdso2c
6060

6161
quiet_cmd_vdso2c = VDSO2C $@

arch/x86/include/asm/inat.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
/* AVX VEX prefixes */
4949
#define INAT_PFX_VEX2 13 /* 2-bytes VEX prefix */
5050
#define INAT_PFX_VEX3 14 /* 3-bytes VEX prefix */
51+
#define INAT_PFX_EVEX 15 /* EVEX prefix */
5152

5253
#define INAT_LSTPFX_MAX 3
5354
#define INAT_LGCPFX_MAX 11
@@ -89,6 +90,7 @@
8990
#define INAT_VARIANT (1 << (INAT_FLAG_OFFS + 4))
9091
#define INAT_VEXOK (1 << (INAT_FLAG_OFFS + 5))
9192
#define INAT_VEXONLY (1 << (INAT_FLAG_OFFS + 6))
93+
#define INAT_EVEXONLY (1 << (INAT_FLAG_OFFS + 7))
9294
/* Attribute making macros for attribute tables */
9395
#define INAT_MAKE_PREFIX(pfx) (pfx << INAT_PFX_OFFS)
9496
#define INAT_MAKE_ESCAPE(esc) (esc << INAT_ESC_OFFS)
@@ -141,7 +143,13 @@ static inline int inat_last_prefix_id(insn_attr_t attr)
141143
static inline int inat_is_vex_prefix(insn_attr_t attr)
142144
{
143145
attr &= INAT_PFX_MASK;
144-
return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3;
146+
return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
147+
attr == INAT_PFX_EVEX;
148+
}
149+
150+
static inline int inat_is_evex_prefix(insn_attr_t attr)
151+
{
152+
return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
145153
}
146154

147155
static inline int inat_is_vex3_prefix(insn_attr_t attr)
@@ -216,6 +224,11 @@ static inline int inat_accept_vex(insn_attr_t attr)
216224

217225
static inline int inat_must_vex(insn_attr_t attr)
218226
{
219-
return attr & INAT_VEXONLY;
227+
return attr & (INAT_VEXONLY | INAT_EVEXONLY);
228+
}
229+
230+
static inline int inat_must_evex(insn_attr_t attr)
231+
{
232+
return attr & INAT_EVEXONLY;
220233
}
221234
#endif

arch/x86/include/asm/insn.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct insn {
9191
#define X86_VEX_B(vex) ((vex) & 0x20) /* VEX3 Byte1 */
9292
#define X86_VEX_L(vex) ((vex) & 0x04) /* VEX3 Byte2, VEX2 Byte1 */
9393
/* VEX bit fields */
94+
#define X86_EVEX_M(vex) ((vex) & 0x03) /* EVEX Byte1 */
9495
#define X86_VEX3_M(vex) ((vex) & 0x1f) /* VEX3 Byte1 */
9596
#define X86_VEX2_M 1 /* VEX2.M always 1 */
9697
#define X86_VEX_V(vex) (((vex) & 0x78) >> 3) /* VEX3 Byte2, VEX2 Byte1 */
@@ -133,6 +134,13 @@ static inline int insn_is_avx(struct insn *insn)
133134
return (insn->vex_prefix.value != 0);
134135
}
135136

137+
static inline int insn_is_evex(struct insn *insn)
138+
{
139+
if (!insn->prefixes.got)
140+
insn_get_prefixes(insn);
141+
return (insn->vex_prefix.nbytes == 4);
142+
}
143+
136144
/* Ensure this instruction is decoded completely */
137145
static inline int insn_complete(struct insn *insn)
138146
{
@@ -144,8 +152,10 @@ static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
144152
{
145153
if (insn->vex_prefix.nbytes == 2) /* 2 bytes VEX */
146154
return X86_VEX2_M;
147-
else
155+
else if (insn->vex_prefix.nbytes == 3) /* 3 bytes VEX */
148156
return X86_VEX3_M(insn->vex_prefix.bytes[1]);
157+
else /* EVEX */
158+
return X86_EVEX_M(insn->vex_prefix.bytes[1]);
149159
}
150160

151161
static inline insn_byte_t insn_vex_p_bits(struct insn *insn)

arch/x86/lib/insn.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,24 @@ void insn_get_prefixes(struct insn *insn)
155155
/*
156156
* In 32-bits mode, if the [7:6] bits (mod bits of
157157
* ModRM) on the second byte are not 11b, it is
158-
* LDS or LES.
158+
* LDS or LES or BOUND.
159159
*/
160160
if (X86_MODRM_MOD(b2) != 3)
161161
goto vex_end;
162162
}
163163
insn->vex_prefix.bytes[0] = b;
164164
insn->vex_prefix.bytes[1] = b2;
165-
if (inat_is_vex3_prefix(attr)) {
165+
if (inat_is_evex_prefix(attr)) {
166+
b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167+
insn->vex_prefix.bytes[2] = b2;
168+
b2 = peek_nbyte_next(insn_byte_t, insn, 3);
169+
insn->vex_prefix.bytes[3] = b2;
170+
insn->vex_prefix.nbytes = 4;
171+
insn->next_byte += 4;
172+
if (insn->x86_64 && X86_VEX_W(b2))
173+
/* VEX.W overrides opnd_size */
174+
insn->opnd_bytes = 8;
175+
} else if (inat_is_vex3_prefix(attr)) {
166176
b2 = peek_nbyte_next(insn_byte_t, insn, 2);
167177
insn->vex_prefix.bytes[2] = b2;
168178
insn->vex_prefix.nbytes = 3;
@@ -221,7 +231,9 @@ void insn_get_opcode(struct insn *insn)
221231
m = insn_vex_m_bits(insn);
222232
p = insn_vex_p_bits(insn);
223233
insn->attr = inat_get_avx_attribute(op, m, p);
224-
if (!inat_accept_vex(insn->attr) && !inat_is_group(insn->attr))
234+
if ((inat_must_evex(insn->attr) && !insn_is_evex(insn)) ||
235+
(!inat_accept_vex(insn->attr) &&
236+
!inat_is_group(insn->attr)))
225237
insn->attr = 0; /* This instruction is bad */
226238
goto end; /* VEX has only 1 byte for opcode */
227239
}

0 commit comments

Comments
 (0)