174fe6c29SRuslan Bukin /*
274fe6c29SRuslan Bukin  * Copyright (c) 2014-2018, Intel Corporation
374fe6c29SRuslan Bukin  *
474fe6c29SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
574fe6c29SRuslan Bukin  * modification, are permitted provided that the following conditions are met:
674fe6c29SRuslan Bukin  *
774fe6c29SRuslan Bukin  *  * Redistributions of source code must retain the above copyright notice,
874fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer.
974fe6c29SRuslan Bukin  *  * Redistributions in binary form must reproduce the above copyright notice,
1074fe6c29SRuslan Bukin  *    this list of conditions and the following disclaimer in the documentation
1174fe6c29SRuslan Bukin  *    and/or other materials provided with the distribution.
1274fe6c29SRuslan Bukin  *  * Neither the name of Intel Corporation nor the names of its contributors
1374fe6c29SRuslan Bukin  *    may be used to endorse or promote products derived from this software
1474fe6c29SRuslan Bukin  *    without specific prior written permission.
1574fe6c29SRuslan Bukin  *
1674fe6c29SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1774fe6c29SRuslan Bukin  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1874fe6c29SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1974fe6c29SRuslan Bukin  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2074fe6c29SRuslan Bukin  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2174fe6c29SRuslan Bukin  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2274fe6c29SRuslan Bukin  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2374fe6c29SRuslan Bukin  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2474fe6c29SRuslan Bukin  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2574fe6c29SRuslan Bukin  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2674fe6c29SRuslan Bukin  * POSSIBILITY OF SUCH DAMAGE.
2774fe6c29SRuslan Bukin  */
2874fe6c29SRuslan Bukin 
2974fe6c29SRuslan Bukin #include "pt_packet_decoder.h"
3074fe6c29SRuslan Bukin #include "pt_decoder_function.h"
3174fe6c29SRuslan Bukin #include "pt_packet.h"
3274fe6c29SRuslan Bukin #include "pt_sync.h"
3374fe6c29SRuslan Bukin #include "pt_config.h"
3474fe6c29SRuslan Bukin #include "pt_opcodes.h"
3574fe6c29SRuslan Bukin 
3674fe6c29SRuslan Bukin #include <string.h>
3774fe6c29SRuslan Bukin #include <stdlib.h>
3874fe6c29SRuslan Bukin 
3974fe6c29SRuslan Bukin 
4074fe6c29SRuslan Bukin int pt_pkt_decoder_init(struct pt_packet_decoder *decoder,
4174fe6c29SRuslan Bukin 			const struct pt_config *config)
4274fe6c29SRuslan Bukin {
4374fe6c29SRuslan Bukin 	int errcode;
4474fe6c29SRuslan Bukin 
4574fe6c29SRuslan Bukin 	if (!decoder || !config)
4674fe6c29SRuslan Bukin 		return -pte_invalid;
4774fe6c29SRuslan Bukin 
4874fe6c29SRuslan Bukin 	memset(decoder, 0, sizeof(*decoder));
4974fe6c29SRuslan Bukin 
5074fe6c29SRuslan Bukin 	errcode = pt_config_from_user(&decoder->config, config);
5174fe6c29SRuslan Bukin 	if (errcode < 0)
5274fe6c29SRuslan Bukin 		return errcode;
5374fe6c29SRuslan Bukin 
5474fe6c29SRuslan Bukin 	return 0;
5574fe6c29SRuslan Bukin }
5674fe6c29SRuslan Bukin 
5774fe6c29SRuslan Bukin struct pt_packet_decoder *pt_pkt_alloc_decoder(const struct pt_config *config)
5874fe6c29SRuslan Bukin {
5974fe6c29SRuslan Bukin 	struct pt_packet_decoder *decoder;
6074fe6c29SRuslan Bukin 	int errcode;
6174fe6c29SRuslan Bukin 
6274fe6c29SRuslan Bukin 	decoder = malloc(sizeof(*decoder));
6374fe6c29SRuslan Bukin 	if (!decoder)
6474fe6c29SRuslan Bukin 		return NULL;
6574fe6c29SRuslan Bukin 
6674fe6c29SRuslan Bukin 	errcode = pt_pkt_decoder_init(decoder, config);
6774fe6c29SRuslan Bukin 	if (errcode < 0) {
6874fe6c29SRuslan Bukin 		free(decoder);
6974fe6c29SRuslan Bukin 		return NULL;
7074fe6c29SRuslan Bukin 	}
7174fe6c29SRuslan Bukin 
7274fe6c29SRuslan Bukin 	return decoder;
7374fe6c29SRuslan Bukin }
7474fe6c29SRuslan Bukin 
7574fe6c29SRuslan Bukin void pt_pkt_decoder_fini(struct pt_packet_decoder *decoder)
7674fe6c29SRuslan Bukin {
7774fe6c29SRuslan Bukin 	(void) decoder;
7874fe6c29SRuslan Bukin 
7974fe6c29SRuslan Bukin 	/* Nothing to do. */
8074fe6c29SRuslan Bukin }
8174fe6c29SRuslan Bukin 
8274fe6c29SRuslan Bukin void pt_pkt_free_decoder(struct pt_packet_decoder *decoder)
8374fe6c29SRuslan Bukin {
8474fe6c29SRuslan Bukin 	pt_pkt_decoder_fini(decoder);
8574fe6c29SRuslan Bukin 	free(decoder);
8674fe6c29SRuslan Bukin }
8774fe6c29SRuslan Bukin 
8874fe6c29SRuslan Bukin int pt_pkt_sync_forward(struct pt_packet_decoder *decoder)
8974fe6c29SRuslan Bukin {
9074fe6c29SRuslan Bukin 	const uint8_t *pos, *sync;
9174fe6c29SRuslan Bukin 	int errcode;
9274fe6c29SRuslan Bukin 
9374fe6c29SRuslan Bukin 	if (!decoder)
9474fe6c29SRuslan Bukin 		return -pte_invalid;
9574fe6c29SRuslan Bukin 
9674fe6c29SRuslan Bukin 	sync = decoder->sync;
9774fe6c29SRuslan Bukin 	pos = decoder->pos;
9874fe6c29SRuslan Bukin 	if (!pos)
9974fe6c29SRuslan Bukin 		pos = decoder->config.begin;
10074fe6c29SRuslan Bukin 
10174fe6c29SRuslan Bukin 	if (pos == sync)
10274fe6c29SRuslan Bukin 		pos += ptps_psb;
10374fe6c29SRuslan Bukin 
10474fe6c29SRuslan Bukin 	errcode = pt_sync_forward(&sync, pos, &decoder->config);
10574fe6c29SRuslan Bukin 	if (errcode < 0)
10674fe6c29SRuslan Bukin 		return errcode;
10774fe6c29SRuslan Bukin 
10874fe6c29SRuslan Bukin 	decoder->sync = sync;
10974fe6c29SRuslan Bukin 	decoder->pos = sync;
11074fe6c29SRuslan Bukin 
11174fe6c29SRuslan Bukin 	return 0;
11274fe6c29SRuslan Bukin }
11374fe6c29SRuslan Bukin 
11474fe6c29SRuslan Bukin int pt_pkt_sync_backward(struct pt_packet_decoder *decoder)
11574fe6c29SRuslan Bukin {
11674fe6c29SRuslan Bukin 	const uint8_t *pos, *sync;
11774fe6c29SRuslan Bukin 	int errcode;
11874fe6c29SRuslan Bukin 
11974fe6c29SRuslan Bukin 	if (!decoder)
12074fe6c29SRuslan Bukin 		return -pte_invalid;
12174fe6c29SRuslan Bukin 
12274fe6c29SRuslan Bukin 	pos = decoder->pos;
12374fe6c29SRuslan Bukin 	if (!pos)
12474fe6c29SRuslan Bukin 		pos = decoder->config.end;
12574fe6c29SRuslan Bukin 
12674fe6c29SRuslan Bukin 	errcode = pt_sync_backward(&sync, pos, &decoder->config);
12774fe6c29SRuslan Bukin 	if (errcode < 0)
12874fe6c29SRuslan Bukin 		return errcode;
12974fe6c29SRuslan Bukin 
13074fe6c29SRuslan Bukin 	decoder->sync = sync;
13174fe6c29SRuslan Bukin 	decoder->pos = sync;
13274fe6c29SRuslan Bukin 
13374fe6c29SRuslan Bukin 	return 0;
13474fe6c29SRuslan Bukin }
13574fe6c29SRuslan Bukin 
13674fe6c29SRuslan Bukin int pt_pkt_sync_set(struct pt_packet_decoder *decoder, uint64_t offset)
13774fe6c29SRuslan Bukin {
13874fe6c29SRuslan Bukin 	const uint8_t *begin, *end, *pos;
13974fe6c29SRuslan Bukin 
14074fe6c29SRuslan Bukin 	if (!decoder)
14174fe6c29SRuslan Bukin 		return -pte_invalid;
14274fe6c29SRuslan Bukin 
14374fe6c29SRuslan Bukin 	begin = decoder->config.begin;
14474fe6c29SRuslan Bukin 	end = decoder->config.end;
14574fe6c29SRuslan Bukin 	pos = begin + offset;
14674fe6c29SRuslan Bukin 
14774fe6c29SRuslan Bukin 	if (end < pos || pos < begin)
14874fe6c29SRuslan Bukin 		return -pte_eos;
14974fe6c29SRuslan Bukin 
15074fe6c29SRuslan Bukin 	decoder->sync = pos;
15174fe6c29SRuslan Bukin 	decoder->pos = pos;
15274fe6c29SRuslan Bukin 
15374fe6c29SRuslan Bukin 	return 0;
15474fe6c29SRuslan Bukin }
15574fe6c29SRuslan Bukin 
15674fe6c29SRuslan Bukin int pt_pkt_get_offset(const struct pt_packet_decoder *decoder, uint64_t *offset)
15774fe6c29SRuslan Bukin {
15874fe6c29SRuslan Bukin 	const uint8_t *begin, *pos;
15974fe6c29SRuslan Bukin 
16074fe6c29SRuslan Bukin 	if (!decoder || !offset)
16174fe6c29SRuslan Bukin 		return -pte_invalid;
16274fe6c29SRuslan Bukin 
16374fe6c29SRuslan Bukin 	begin = decoder->config.begin;
16474fe6c29SRuslan Bukin 	pos = decoder->pos;
16574fe6c29SRuslan Bukin 
16674fe6c29SRuslan Bukin 	if (!pos)
16774fe6c29SRuslan Bukin 		return -pte_nosync;
16874fe6c29SRuslan Bukin 
16974fe6c29SRuslan Bukin 	*offset = pos - begin;
17074fe6c29SRuslan Bukin 	return 0;
17174fe6c29SRuslan Bukin }
17274fe6c29SRuslan Bukin 
17374fe6c29SRuslan Bukin int pt_pkt_get_sync_offset(const struct pt_packet_decoder *decoder,
17474fe6c29SRuslan Bukin 			   uint64_t *offset)
17574fe6c29SRuslan Bukin {
17674fe6c29SRuslan Bukin 	const uint8_t *begin, *sync;
17774fe6c29SRuslan Bukin 
17874fe6c29SRuslan Bukin 	if (!decoder || !offset)
17974fe6c29SRuslan Bukin 		return -pte_invalid;
18074fe6c29SRuslan Bukin 
18174fe6c29SRuslan Bukin 	begin = decoder->config.begin;
18274fe6c29SRuslan Bukin 	sync = decoder->sync;
18374fe6c29SRuslan Bukin 
18474fe6c29SRuslan Bukin 	if (!sync)
18574fe6c29SRuslan Bukin 		return -pte_nosync;
18674fe6c29SRuslan Bukin 
18774fe6c29SRuslan Bukin 	*offset = sync - begin;
18874fe6c29SRuslan Bukin 	return 0;
18974fe6c29SRuslan Bukin }
19074fe6c29SRuslan Bukin 
19174fe6c29SRuslan Bukin const struct pt_config *
19274fe6c29SRuslan Bukin pt_pkt_get_config(const struct pt_packet_decoder *decoder)
19374fe6c29SRuslan Bukin {
19474fe6c29SRuslan Bukin 	if (!decoder)
19574fe6c29SRuslan Bukin 		return NULL;
19674fe6c29SRuslan Bukin 
19774fe6c29SRuslan Bukin 	return &decoder->config;
19874fe6c29SRuslan Bukin }
19974fe6c29SRuslan Bukin 
20074fe6c29SRuslan Bukin static inline int pkt_to_user(struct pt_packet *upkt, size_t size,
20174fe6c29SRuslan Bukin 			      const struct pt_packet *pkt)
20274fe6c29SRuslan Bukin {
20374fe6c29SRuslan Bukin 	if (!upkt || !pkt)
20474fe6c29SRuslan Bukin 		return -pte_internal;
20574fe6c29SRuslan Bukin 
20674fe6c29SRuslan Bukin 	if (upkt == pkt)
20774fe6c29SRuslan Bukin 		return 0;
20874fe6c29SRuslan Bukin 
20974fe6c29SRuslan Bukin 	/* Zero out any unknown bytes. */
21074fe6c29SRuslan Bukin 	if (sizeof(*pkt) < size) {
21174fe6c29SRuslan Bukin 		memset(upkt + sizeof(*pkt), 0, size - sizeof(*pkt));
21274fe6c29SRuslan Bukin 
21374fe6c29SRuslan Bukin 		size = sizeof(*pkt);
21474fe6c29SRuslan Bukin 	}
21574fe6c29SRuslan Bukin 
21674fe6c29SRuslan Bukin 	memcpy(upkt, pkt, size);
21774fe6c29SRuslan Bukin 
21874fe6c29SRuslan Bukin 	return 0;
21974fe6c29SRuslan Bukin }
22074fe6c29SRuslan Bukin 
22174fe6c29SRuslan Bukin int pt_pkt_next(struct pt_packet_decoder *decoder, struct pt_packet *packet,
22274fe6c29SRuslan Bukin 		size_t psize)
22374fe6c29SRuslan Bukin {
22474fe6c29SRuslan Bukin 	const struct pt_decoder_function *dfun;
22574fe6c29SRuslan Bukin 	struct pt_packet pkt, *ppkt;
22674fe6c29SRuslan Bukin 	int errcode, size;
22774fe6c29SRuslan Bukin 
22874fe6c29SRuslan Bukin 	if (!packet || !decoder)
22974fe6c29SRuslan Bukin 		return -pte_invalid;
23074fe6c29SRuslan Bukin 
23174fe6c29SRuslan Bukin 	ppkt = psize == sizeof(pkt) ? packet : &pkt;
23274fe6c29SRuslan Bukin 
23374fe6c29SRuslan Bukin 	errcode = pt_df_fetch(&dfun, decoder->pos, &decoder->config);
23474fe6c29SRuslan Bukin 	if (errcode < 0)
23574fe6c29SRuslan Bukin 		return errcode;
23674fe6c29SRuslan Bukin 
23774fe6c29SRuslan Bukin 	if (!dfun)
23874fe6c29SRuslan Bukin 		return -pte_internal;
23974fe6c29SRuslan Bukin 
24074fe6c29SRuslan Bukin 	if (!dfun->packet)
24174fe6c29SRuslan Bukin 		return -pte_internal;
24274fe6c29SRuslan Bukin 
24374fe6c29SRuslan Bukin 	size = dfun->packet(decoder, ppkt);
24474fe6c29SRuslan Bukin 	if (size < 0)
24574fe6c29SRuslan Bukin 		return size;
24674fe6c29SRuslan Bukin 
24774fe6c29SRuslan Bukin 	errcode = pkt_to_user(packet, psize, ppkt);
24874fe6c29SRuslan Bukin 	if (errcode < 0)
24974fe6c29SRuslan Bukin 		return errcode;
25074fe6c29SRuslan Bukin 
25174fe6c29SRuslan Bukin 	decoder->pos += size;
25274fe6c29SRuslan Bukin 
25374fe6c29SRuslan Bukin 	return size;
25474fe6c29SRuslan Bukin }
25574fe6c29SRuslan Bukin 
25674fe6c29SRuslan Bukin int pt_pkt_decode_unknown(struct pt_packet_decoder *decoder,
25774fe6c29SRuslan Bukin 			  struct pt_packet *packet)
25874fe6c29SRuslan Bukin {
25974fe6c29SRuslan Bukin 	int size;
26074fe6c29SRuslan Bukin 
26174fe6c29SRuslan Bukin 	if (!decoder)
26274fe6c29SRuslan Bukin 		return -pte_internal;
26374fe6c29SRuslan Bukin 
26474fe6c29SRuslan Bukin 	size = pt_pkt_read_unknown(packet, decoder->pos, &decoder->config);
26574fe6c29SRuslan Bukin 	if (size < 0)
26674fe6c29SRuslan Bukin 		return size;
26774fe6c29SRuslan Bukin 
26874fe6c29SRuslan Bukin 	return size;
26974fe6c29SRuslan Bukin }
27074fe6c29SRuslan Bukin 
27174fe6c29SRuslan Bukin int pt_pkt_decode_pad(struct pt_packet_decoder *decoder,
27274fe6c29SRuslan Bukin 		      struct pt_packet *packet)
27374fe6c29SRuslan Bukin {
27474fe6c29SRuslan Bukin 	(void) decoder;
27574fe6c29SRuslan Bukin 
27674fe6c29SRuslan Bukin 	if (!packet)
27774fe6c29SRuslan Bukin 		return -pte_internal;
27874fe6c29SRuslan Bukin 
27974fe6c29SRuslan Bukin 	packet->type = ppt_pad;
28074fe6c29SRuslan Bukin 	packet->size = ptps_pad;
28174fe6c29SRuslan Bukin 
28274fe6c29SRuslan Bukin 	return ptps_pad;
28374fe6c29SRuslan Bukin }
28474fe6c29SRuslan Bukin 
28574fe6c29SRuslan Bukin int pt_pkt_decode_psb(struct pt_packet_decoder *decoder,
28674fe6c29SRuslan Bukin 		      struct pt_packet *packet)
28774fe6c29SRuslan Bukin {
28874fe6c29SRuslan Bukin 	int size;
28974fe6c29SRuslan Bukin 
29074fe6c29SRuslan Bukin 	if (!decoder)
29174fe6c29SRuslan Bukin 		return -pte_internal;
29274fe6c29SRuslan Bukin 
29374fe6c29SRuslan Bukin 	size = pt_pkt_read_psb(decoder->pos, &decoder->config);
29474fe6c29SRuslan Bukin 	if (size < 0)
29574fe6c29SRuslan Bukin 		return size;
29674fe6c29SRuslan Bukin 
29774fe6c29SRuslan Bukin 	packet->type = ppt_psb;
29874fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
29974fe6c29SRuslan Bukin 
30074fe6c29SRuslan Bukin 	return size;
30174fe6c29SRuslan Bukin }
30274fe6c29SRuslan Bukin 
30374fe6c29SRuslan Bukin int pt_pkt_decode_tip(struct pt_packet_decoder *decoder,
30474fe6c29SRuslan Bukin 		      struct pt_packet *packet)
30574fe6c29SRuslan Bukin {
30674fe6c29SRuslan Bukin 	int size;
30774fe6c29SRuslan Bukin 
30874fe6c29SRuslan Bukin 	if (!decoder || !packet)
30974fe6c29SRuslan Bukin 		return -pte_internal;
31074fe6c29SRuslan Bukin 
31174fe6c29SRuslan Bukin 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
31274fe6c29SRuslan Bukin 			      &decoder->config);
31374fe6c29SRuslan Bukin 	if (size < 0)
31474fe6c29SRuslan Bukin 		return size;
31574fe6c29SRuslan Bukin 
31674fe6c29SRuslan Bukin 	packet->type = ppt_tip;
31774fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
31874fe6c29SRuslan Bukin 
31974fe6c29SRuslan Bukin 	return size;
32074fe6c29SRuslan Bukin }
32174fe6c29SRuslan Bukin 
32274fe6c29SRuslan Bukin int pt_pkt_decode_tnt_8(struct pt_packet_decoder *decoder,
32374fe6c29SRuslan Bukin 			struct pt_packet *packet)
32474fe6c29SRuslan Bukin {
32574fe6c29SRuslan Bukin 	int size;
32674fe6c29SRuslan Bukin 
32774fe6c29SRuslan Bukin 	if (!decoder || !packet)
32874fe6c29SRuslan Bukin 		return -pte_internal;
32974fe6c29SRuslan Bukin 
33074fe6c29SRuslan Bukin 	size = pt_pkt_read_tnt_8(&packet->payload.tnt, decoder->pos,
33174fe6c29SRuslan Bukin 				 &decoder->config);
33274fe6c29SRuslan Bukin 	if (size < 0)
33374fe6c29SRuslan Bukin 		return size;
33474fe6c29SRuslan Bukin 
33574fe6c29SRuslan Bukin 	packet->type = ppt_tnt_8;
33674fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
33774fe6c29SRuslan Bukin 
33874fe6c29SRuslan Bukin 	return size;
33974fe6c29SRuslan Bukin }
34074fe6c29SRuslan Bukin 
34174fe6c29SRuslan Bukin int pt_pkt_decode_tnt_64(struct pt_packet_decoder *decoder,
34274fe6c29SRuslan Bukin 			 struct pt_packet *packet)
34374fe6c29SRuslan Bukin {
34474fe6c29SRuslan Bukin 	int size;
34574fe6c29SRuslan Bukin 
34674fe6c29SRuslan Bukin 	if (!decoder || !packet)
34774fe6c29SRuslan Bukin 		return -pte_internal;
34874fe6c29SRuslan Bukin 
34974fe6c29SRuslan Bukin 	size = pt_pkt_read_tnt_64(&packet->payload.tnt, decoder->pos,
35074fe6c29SRuslan Bukin 				  &decoder->config);
35174fe6c29SRuslan Bukin 	if (size < 0)
35274fe6c29SRuslan Bukin 		return size;
35374fe6c29SRuslan Bukin 
35474fe6c29SRuslan Bukin 	packet->type = ppt_tnt_64;
35574fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
35674fe6c29SRuslan Bukin 
35774fe6c29SRuslan Bukin 	return size;
35874fe6c29SRuslan Bukin }
35974fe6c29SRuslan Bukin 
36074fe6c29SRuslan Bukin int pt_pkt_decode_tip_pge(struct pt_packet_decoder *decoder,
36174fe6c29SRuslan Bukin 			  struct pt_packet *packet)
36274fe6c29SRuslan Bukin {
36374fe6c29SRuslan Bukin 	int size;
36474fe6c29SRuslan Bukin 
36574fe6c29SRuslan Bukin 	if (!decoder || !packet)
36674fe6c29SRuslan Bukin 		return -pte_internal;
36774fe6c29SRuslan Bukin 
36874fe6c29SRuslan Bukin 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
36974fe6c29SRuslan Bukin 			      &decoder->config);
37074fe6c29SRuslan Bukin 	if (size < 0)
37174fe6c29SRuslan Bukin 		return size;
37274fe6c29SRuslan Bukin 
37374fe6c29SRuslan Bukin 	packet->type = ppt_tip_pge;
37474fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
37574fe6c29SRuslan Bukin 
37674fe6c29SRuslan Bukin 	return size;
37774fe6c29SRuslan Bukin }
37874fe6c29SRuslan Bukin 
37974fe6c29SRuslan Bukin int pt_pkt_decode_tip_pgd(struct pt_packet_decoder *decoder,
38074fe6c29SRuslan Bukin 			  struct pt_packet *packet)
38174fe6c29SRuslan Bukin {
38274fe6c29SRuslan Bukin 	int size;
38374fe6c29SRuslan Bukin 
38474fe6c29SRuslan Bukin 	if (!decoder || !packet)
38574fe6c29SRuslan Bukin 		return -pte_internal;
38674fe6c29SRuslan Bukin 
38774fe6c29SRuslan Bukin 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
38874fe6c29SRuslan Bukin 			      &decoder->config);
38974fe6c29SRuslan Bukin 	if (size < 0)
39074fe6c29SRuslan Bukin 		return size;
39174fe6c29SRuslan Bukin 
39274fe6c29SRuslan Bukin 	packet->type = ppt_tip_pgd;
39374fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
39474fe6c29SRuslan Bukin 
39574fe6c29SRuslan Bukin 	return size;
39674fe6c29SRuslan Bukin }
39774fe6c29SRuslan Bukin 
39874fe6c29SRuslan Bukin int pt_pkt_decode_fup(struct pt_packet_decoder *decoder,
39974fe6c29SRuslan Bukin 		      struct pt_packet *packet)
40074fe6c29SRuslan Bukin {
40174fe6c29SRuslan Bukin 	int size;
40274fe6c29SRuslan Bukin 
40374fe6c29SRuslan Bukin 	if (!decoder || !packet)
40474fe6c29SRuslan Bukin 		return -pte_internal;
40574fe6c29SRuslan Bukin 
40674fe6c29SRuslan Bukin 	size = pt_pkt_read_ip(&packet->payload.ip, decoder->pos,
40774fe6c29SRuslan Bukin 			      &decoder->config);
40874fe6c29SRuslan Bukin 	if (size < 0)
40974fe6c29SRuslan Bukin 		return size;
41074fe6c29SRuslan Bukin 
41174fe6c29SRuslan Bukin 	packet->type = ppt_fup;
41274fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
41374fe6c29SRuslan Bukin 
41474fe6c29SRuslan Bukin 	return size;
41574fe6c29SRuslan Bukin }
41674fe6c29SRuslan Bukin 
41774fe6c29SRuslan Bukin int pt_pkt_decode_pip(struct pt_packet_decoder *decoder,
41874fe6c29SRuslan Bukin 		      struct pt_packet *packet)
41974fe6c29SRuslan Bukin {
42074fe6c29SRuslan Bukin 	int size;
42174fe6c29SRuslan Bukin 
42274fe6c29SRuslan Bukin 	if (!decoder || !packet)
42374fe6c29SRuslan Bukin 		return -pte_internal;
42474fe6c29SRuslan Bukin 
42574fe6c29SRuslan Bukin 	size = pt_pkt_read_pip(&packet->payload.pip, decoder->pos,
42674fe6c29SRuslan Bukin 			       &decoder->config);
42774fe6c29SRuslan Bukin 	if (size < 0)
42874fe6c29SRuslan Bukin 		return size;
42974fe6c29SRuslan Bukin 
43074fe6c29SRuslan Bukin 	packet->type = ppt_pip;
43174fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
43274fe6c29SRuslan Bukin 
43374fe6c29SRuslan Bukin 	return size;
43474fe6c29SRuslan Bukin }
43574fe6c29SRuslan Bukin 
43674fe6c29SRuslan Bukin int pt_pkt_decode_ovf(struct pt_packet_decoder *decoder,
43774fe6c29SRuslan Bukin 		      struct pt_packet *packet)
43874fe6c29SRuslan Bukin {
43974fe6c29SRuslan Bukin 	(void) decoder;
44074fe6c29SRuslan Bukin 
44174fe6c29SRuslan Bukin 	if (!packet)
44274fe6c29SRuslan Bukin 		return -pte_internal;
44374fe6c29SRuslan Bukin 
44474fe6c29SRuslan Bukin 	packet->type = ppt_ovf;
44574fe6c29SRuslan Bukin 	packet->size = ptps_ovf;
44674fe6c29SRuslan Bukin 
44774fe6c29SRuslan Bukin 	return ptps_ovf;
44874fe6c29SRuslan Bukin }
44974fe6c29SRuslan Bukin 
45074fe6c29SRuslan Bukin int pt_pkt_decode_mode(struct pt_packet_decoder *decoder,
45174fe6c29SRuslan Bukin 		       struct pt_packet *packet)
45274fe6c29SRuslan Bukin {
45374fe6c29SRuslan Bukin 	int size;
45474fe6c29SRuslan Bukin 
45574fe6c29SRuslan Bukin 	if (!decoder || !packet)
45674fe6c29SRuslan Bukin 		return -pte_internal;
45774fe6c29SRuslan Bukin 
45874fe6c29SRuslan Bukin 	size = pt_pkt_read_mode(&packet->payload.mode, decoder->pos,
45974fe6c29SRuslan Bukin 				&decoder->config);
46074fe6c29SRuslan Bukin 	if (size < 0)
46174fe6c29SRuslan Bukin 		return size;
46274fe6c29SRuslan Bukin 
46374fe6c29SRuslan Bukin 	packet->type = ppt_mode;
46474fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
46574fe6c29SRuslan Bukin 
46674fe6c29SRuslan Bukin 	return size;
46774fe6c29SRuslan Bukin }
46874fe6c29SRuslan Bukin 
46974fe6c29SRuslan Bukin int pt_pkt_decode_psbend(struct pt_packet_decoder *decoder,
47074fe6c29SRuslan Bukin 			 struct pt_packet *packet)
47174fe6c29SRuslan Bukin {
47274fe6c29SRuslan Bukin 	(void) decoder;
47374fe6c29SRuslan Bukin 
47474fe6c29SRuslan Bukin 	if (!packet)
47574fe6c29SRuslan Bukin 		return -pte_internal;
47674fe6c29SRuslan Bukin 
47774fe6c29SRuslan Bukin 	packet->type = ppt_psbend;
47874fe6c29SRuslan Bukin 	packet->size = ptps_psbend;
47974fe6c29SRuslan Bukin 
48074fe6c29SRuslan Bukin 	return ptps_psbend;
48174fe6c29SRuslan Bukin }
48274fe6c29SRuslan Bukin 
48374fe6c29SRuslan Bukin int pt_pkt_decode_tsc(struct pt_packet_decoder *decoder,
48474fe6c29SRuslan Bukin 		      struct pt_packet *packet)
48574fe6c29SRuslan Bukin {
48674fe6c29SRuslan Bukin 	int size;
48774fe6c29SRuslan Bukin 
48874fe6c29SRuslan Bukin 	if (!decoder || !packet)
48974fe6c29SRuslan Bukin 		return -pte_internal;
49074fe6c29SRuslan Bukin 
49174fe6c29SRuslan Bukin 	size = pt_pkt_read_tsc(&packet->payload.tsc, decoder->pos,
49274fe6c29SRuslan Bukin 			       &decoder->config);
49374fe6c29SRuslan Bukin 	if (size < 0)
49474fe6c29SRuslan Bukin 		return size;
49574fe6c29SRuslan Bukin 
49674fe6c29SRuslan Bukin 	packet->type = ppt_tsc;
49774fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
49874fe6c29SRuslan Bukin 
49974fe6c29SRuslan Bukin 	return size;
50074fe6c29SRuslan Bukin }
50174fe6c29SRuslan Bukin 
50274fe6c29SRuslan Bukin int pt_pkt_decode_cbr(struct pt_packet_decoder *decoder,
50374fe6c29SRuslan Bukin 		      struct pt_packet *packet)
50474fe6c29SRuslan Bukin {
50574fe6c29SRuslan Bukin 	int size;
50674fe6c29SRuslan Bukin 
50774fe6c29SRuslan Bukin 	if (!decoder || !packet)
50874fe6c29SRuslan Bukin 		return -pte_internal;
50974fe6c29SRuslan Bukin 
51074fe6c29SRuslan Bukin 	size = pt_pkt_read_cbr(&packet->payload.cbr, decoder->pos,
51174fe6c29SRuslan Bukin 			       &decoder->config);
51274fe6c29SRuslan Bukin 	if (size < 0)
51374fe6c29SRuslan Bukin 		return size;
51474fe6c29SRuslan Bukin 
51574fe6c29SRuslan Bukin 	packet->type = ppt_cbr;
51674fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
51774fe6c29SRuslan Bukin 
51874fe6c29SRuslan Bukin 	return size;
51974fe6c29SRuslan Bukin }
52074fe6c29SRuslan Bukin 
52174fe6c29SRuslan Bukin int pt_pkt_decode_tma(struct pt_packet_decoder *decoder,
52274fe6c29SRuslan Bukin 		      struct pt_packet *packet)
52374fe6c29SRuslan Bukin {
52474fe6c29SRuslan Bukin 	int size;
52574fe6c29SRuslan Bukin 
52674fe6c29SRuslan Bukin 	if (!decoder || !packet)
52774fe6c29SRuslan Bukin 		return -pte_internal;
52874fe6c29SRuslan Bukin 
52974fe6c29SRuslan Bukin 	size = pt_pkt_read_tma(&packet->payload.tma, decoder->pos,
53074fe6c29SRuslan Bukin 			       &decoder->config);
53174fe6c29SRuslan Bukin 	if (size < 0)
53274fe6c29SRuslan Bukin 		return size;
53374fe6c29SRuslan Bukin 
53474fe6c29SRuslan Bukin 	packet->type = ppt_tma;
53574fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
53674fe6c29SRuslan Bukin 
53774fe6c29SRuslan Bukin 	return size;
53874fe6c29SRuslan Bukin }
53974fe6c29SRuslan Bukin 
54074fe6c29SRuslan Bukin int pt_pkt_decode_mtc(struct pt_packet_decoder *decoder,
54174fe6c29SRuslan Bukin 		      struct pt_packet *packet)
54274fe6c29SRuslan Bukin {
54374fe6c29SRuslan Bukin 	int size;
54474fe6c29SRuslan Bukin 
54574fe6c29SRuslan Bukin 	if (!decoder || !packet)
54674fe6c29SRuslan Bukin 		return -pte_internal;
54774fe6c29SRuslan Bukin 
54874fe6c29SRuslan Bukin 	size = pt_pkt_read_mtc(&packet->payload.mtc, decoder->pos,
54974fe6c29SRuslan Bukin 			       &decoder->config);
55074fe6c29SRuslan Bukin 	if (size < 0)
55174fe6c29SRuslan Bukin 		return size;
55274fe6c29SRuslan Bukin 
55374fe6c29SRuslan Bukin 	packet->type = ppt_mtc;
55474fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
55574fe6c29SRuslan Bukin 
55674fe6c29SRuslan Bukin 	return size;
55774fe6c29SRuslan Bukin }
55874fe6c29SRuslan Bukin 
55974fe6c29SRuslan Bukin int pt_pkt_decode_cyc(struct pt_packet_decoder *decoder,
56074fe6c29SRuslan Bukin 		      struct pt_packet *packet)
56174fe6c29SRuslan Bukin {
56274fe6c29SRuslan Bukin 	int size;
56374fe6c29SRuslan Bukin 
56474fe6c29SRuslan Bukin 	if (!decoder || !packet)
56574fe6c29SRuslan Bukin 		return -pte_internal;
56674fe6c29SRuslan Bukin 
56774fe6c29SRuslan Bukin 	size = pt_pkt_read_cyc(&packet->payload.cyc, decoder->pos,
56874fe6c29SRuslan Bukin 			       &decoder->config);
56974fe6c29SRuslan Bukin 	if (size < 0)
57074fe6c29SRuslan Bukin 		return size;
57174fe6c29SRuslan Bukin 
57274fe6c29SRuslan Bukin 	packet->type = ppt_cyc;
57374fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
57474fe6c29SRuslan Bukin 
57574fe6c29SRuslan Bukin 	return size;
57674fe6c29SRuslan Bukin }
57774fe6c29SRuslan Bukin 
57874fe6c29SRuslan Bukin int pt_pkt_decode_stop(struct pt_packet_decoder *decoder,
57974fe6c29SRuslan Bukin 		       struct pt_packet *packet)
58074fe6c29SRuslan Bukin {
58174fe6c29SRuslan Bukin 	(void) decoder;
58274fe6c29SRuslan Bukin 
58374fe6c29SRuslan Bukin 	if (!packet)
58474fe6c29SRuslan Bukin 		return -pte_internal;
58574fe6c29SRuslan Bukin 
58674fe6c29SRuslan Bukin 	packet->type = ppt_stop;
58774fe6c29SRuslan Bukin 	packet->size = ptps_stop;
58874fe6c29SRuslan Bukin 
58974fe6c29SRuslan Bukin 	return ptps_stop;
59074fe6c29SRuslan Bukin }
59174fe6c29SRuslan Bukin 
59274fe6c29SRuslan Bukin int pt_pkt_decode_vmcs(struct pt_packet_decoder *decoder,
59374fe6c29SRuslan Bukin 		       struct pt_packet *packet)
59474fe6c29SRuslan Bukin {
59574fe6c29SRuslan Bukin 	int size;
59674fe6c29SRuslan Bukin 
59774fe6c29SRuslan Bukin 	if (!decoder || !packet)
59874fe6c29SRuslan Bukin 		return -pte_internal;
59974fe6c29SRuslan Bukin 
60074fe6c29SRuslan Bukin 	size = pt_pkt_read_vmcs(&packet->payload.vmcs, decoder->pos,
60174fe6c29SRuslan Bukin 			       &decoder->config);
60274fe6c29SRuslan Bukin 	if (size < 0)
60374fe6c29SRuslan Bukin 		return size;
60474fe6c29SRuslan Bukin 
60574fe6c29SRuslan Bukin 	packet->type = ppt_vmcs;
60674fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
60774fe6c29SRuslan Bukin 
60874fe6c29SRuslan Bukin 	return size;
60974fe6c29SRuslan Bukin }
61074fe6c29SRuslan Bukin 
61174fe6c29SRuslan Bukin int pt_pkt_decode_mnt(struct pt_packet_decoder *decoder,
61274fe6c29SRuslan Bukin 		      struct pt_packet *packet)
61374fe6c29SRuslan Bukin {
61474fe6c29SRuslan Bukin 	int size;
61574fe6c29SRuslan Bukin 
61674fe6c29SRuslan Bukin 	if (!decoder || !packet)
61774fe6c29SRuslan Bukin 		return -pte_internal;
61874fe6c29SRuslan Bukin 
61974fe6c29SRuslan Bukin 	size = pt_pkt_read_mnt(&packet->payload.mnt, decoder->pos,
62074fe6c29SRuslan Bukin 			       &decoder->config);
62174fe6c29SRuslan Bukin 	if (size < 0)
62274fe6c29SRuslan Bukin 		return size;
62374fe6c29SRuslan Bukin 
62474fe6c29SRuslan Bukin 	packet->type = ppt_mnt;
62574fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
62674fe6c29SRuslan Bukin 
62774fe6c29SRuslan Bukin 	return size;
62874fe6c29SRuslan Bukin }
62974fe6c29SRuslan Bukin 
63074fe6c29SRuslan Bukin int pt_pkt_decode_exstop(struct pt_packet_decoder *decoder,
63174fe6c29SRuslan Bukin 			 struct pt_packet *packet)
63274fe6c29SRuslan Bukin {
63374fe6c29SRuslan Bukin 	int size;
63474fe6c29SRuslan Bukin 
63574fe6c29SRuslan Bukin 	if (!decoder || !packet)
63674fe6c29SRuslan Bukin 		return -pte_internal;
63774fe6c29SRuslan Bukin 
63874fe6c29SRuslan Bukin 	size = pt_pkt_read_exstop(&packet->payload.exstop, decoder->pos,
63974fe6c29SRuslan Bukin 				  &decoder->config);
64074fe6c29SRuslan Bukin 	if (size < 0)
64174fe6c29SRuslan Bukin 		return size;
64274fe6c29SRuslan Bukin 
64374fe6c29SRuslan Bukin 	packet->type = ppt_exstop;
64474fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
64574fe6c29SRuslan Bukin 
64674fe6c29SRuslan Bukin 	return size;
64774fe6c29SRuslan Bukin }
64874fe6c29SRuslan Bukin 
64974fe6c29SRuslan Bukin int pt_pkt_decode_mwait(struct pt_packet_decoder *decoder,
65074fe6c29SRuslan Bukin 			struct pt_packet *packet)
65174fe6c29SRuslan Bukin {
65274fe6c29SRuslan Bukin 	int size;
65374fe6c29SRuslan Bukin 
65474fe6c29SRuslan Bukin 	if (!decoder || !packet)
65574fe6c29SRuslan Bukin 		return -pte_internal;
65674fe6c29SRuslan Bukin 
65774fe6c29SRuslan Bukin 	size = pt_pkt_read_mwait(&packet->payload.mwait, decoder->pos,
65874fe6c29SRuslan Bukin 				 &decoder->config);
65974fe6c29SRuslan Bukin 	if (size < 0)
66074fe6c29SRuslan Bukin 		return size;
66174fe6c29SRuslan Bukin 
66274fe6c29SRuslan Bukin 	packet->type = ppt_mwait;
66374fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
66474fe6c29SRuslan Bukin 
66574fe6c29SRuslan Bukin 	return size;
66674fe6c29SRuslan Bukin }
66774fe6c29SRuslan Bukin 
66874fe6c29SRuslan Bukin int pt_pkt_decode_pwre(struct pt_packet_decoder *decoder,
66974fe6c29SRuslan Bukin 		       struct pt_packet *packet)
67074fe6c29SRuslan Bukin {
67174fe6c29SRuslan Bukin 	int size;
67274fe6c29SRuslan Bukin 
67374fe6c29SRuslan Bukin 	if (!decoder || !packet)
67474fe6c29SRuslan Bukin 		return -pte_internal;
67574fe6c29SRuslan Bukin 
67674fe6c29SRuslan Bukin 	size = pt_pkt_read_pwre(&packet->payload.pwre, decoder->pos,
67774fe6c29SRuslan Bukin 				&decoder->config);
67874fe6c29SRuslan Bukin 	if (size < 0)
67974fe6c29SRuslan Bukin 		return size;
68074fe6c29SRuslan Bukin 
68174fe6c29SRuslan Bukin 	packet->type = ppt_pwre;
68274fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
68374fe6c29SRuslan Bukin 
68474fe6c29SRuslan Bukin 	return size;
68574fe6c29SRuslan Bukin }
68674fe6c29SRuslan Bukin 
68774fe6c29SRuslan Bukin int pt_pkt_decode_pwrx(struct pt_packet_decoder *decoder,
68874fe6c29SRuslan Bukin 		       struct pt_packet *packet)
68974fe6c29SRuslan Bukin {
69074fe6c29SRuslan Bukin 	int size;
69174fe6c29SRuslan Bukin 
69274fe6c29SRuslan Bukin 	if (!decoder || !packet)
69374fe6c29SRuslan Bukin 		return -pte_internal;
69474fe6c29SRuslan Bukin 
69574fe6c29SRuslan Bukin 	size = pt_pkt_read_pwrx(&packet->payload.pwrx, decoder->pos,
69674fe6c29SRuslan Bukin 				&decoder->config);
69774fe6c29SRuslan Bukin 	if (size < 0)
69874fe6c29SRuslan Bukin 		return size;
69974fe6c29SRuslan Bukin 
70074fe6c29SRuslan Bukin 	packet->type = ppt_pwrx;
70174fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
70274fe6c29SRuslan Bukin 
70374fe6c29SRuslan Bukin 	return size;
70474fe6c29SRuslan Bukin }
70574fe6c29SRuslan Bukin 
70674fe6c29SRuslan Bukin int pt_pkt_decode_ptw(struct pt_packet_decoder *decoder,
70774fe6c29SRuslan Bukin 		      struct pt_packet *packet)
70874fe6c29SRuslan Bukin {
70974fe6c29SRuslan Bukin 	int size;
71074fe6c29SRuslan Bukin 
71174fe6c29SRuslan Bukin 	if (!decoder || !packet)
71274fe6c29SRuslan Bukin 		return -pte_internal;
71374fe6c29SRuslan Bukin 
71474fe6c29SRuslan Bukin 	size = pt_pkt_read_ptw(&packet->payload.ptw, decoder->pos,
71574fe6c29SRuslan Bukin 			       &decoder->config);
71674fe6c29SRuslan Bukin 	if (size < 0)
71774fe6c29SRuslan Bukin 		return size;
71874fe6c29SRuslan Bukin 
71974fe6c29SRuslan Bukin 	packet->type = ppt_ptw;
72074fe6c29SRuslan Bukin 	packet->size = (uint8_t) size;
72174fe6c29SRuslan Bukin 
72274fe6c29SRuslan Bukin 	return size;
72374fe6c29SRuslan Bukin }
724