|
Packit |
b1f7ae |
/*
|
|
Packit |
b1f7ae |
* Copyright (c) 2014-2017, Intel Corporation
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
b1f7ae |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* * Redistributions of source code must retain the above copyright notice,
|
|
Packit |
b1f7ae |
* this list of conditions and the following disclaimer.
|
|
Packit |
b1f7ae |
* * Redistributions in binary form must reproduce the above copyright notice,
|
|
Packit |
b1f7ae |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
b1f7ae |
* and/or other materials provided with the distribution.
|
|
Packit |
b1f7ae |
* * Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit |
b1f7ae |
* may be used to endorse or promote products derived from this software
|
|
Packit |
b1f7ae |
* without specific prior written permission.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit |
b1f7ae |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit |
b1f7ae |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit |
b1f7ae |
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
Packit |
b1f7ae |
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
Packit |
b1f7ae |
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
Packit |
b1f7ae |
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
Packit |
b1f7ae |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
Packit |
b1f7ae |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
Packit |
b1f7ae |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
Packit |
b1f7ae |
* POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
b1f7ae |
*/
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
#include "pt_encoder.h"
|
|
Packit |
b1f7ae |
#include "pt_config.h"
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
#include <string.h>
|
|
Packit |
b1f7ae |
#include <stdlib.h>
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encoder_init(struct pt_encoder *encoder, const struct pt_config *config)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
int errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder)
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
memset(encoder, 0, sizeof(*encoder));
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_config_from_user(&encoder->config, config);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = encoder->config.begin;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return 0;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
void pt_encoder_fini(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
(void) encoder;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* Nothing to do. */
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
struct pt_encoder *pt_alloc_encoder(const struct pt_config *config)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_encoder *encoder;
|
|
Packit |
b1f7ae |
int errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder = malloc(sizeof(*encoder));
|
|
Packit |
b1f7ae |
if (!encoder)
|
|
Packit |
b1f7ae |
return NULL;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_encoder_init(encoder, config);
|
|
Packit |
b1f7ae |
if (errcode < 0) {
|
|
Packit |
b1f7ae |
free(encoder);
|
|
Packit |
b1f7ae |
return NULL;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return encoder;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
void pt_free_encoder(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
pt_encoder_fini(encoder);
|
|
Packit |
b1f7ae |
free(encoder);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_enc_sync_set(struct pt_encoder *encoder, uint64_t offset)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
uint8_t *begin, *end, *pos;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder)
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
begin = encoder->config.begin;
|
|
Packit |
b1f7ae |
end = encoder->config.end;
|
|
Packit |
b1f7ae |
pos = begin + offset;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (end < pos || pos < begin)
|
|
Packit |
b1f7ae |
return -pte_eos;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return 0;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_enc_get_offset(struct pt_encoder *encoder, uint64_t *offset)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
const uint8_t *raw, *begin;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder || !offset)
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* The encoder is synchronized at all times. */
|
|
Packit |
b1f7ae |
raw = encoder->pos;
|
|
Packit |
b1f7ae |
if (!raw)
|
|
Packit |
b1f7ae |
return -pte_internal;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
begin = encoder->config.begin;
|
|
Packit |
b1f7ae |
if (!begin)
|
|
Packit |
b1f7ae |
return -pte_internal;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*offset = raw - begin;
|
|
Packit |
b1f7ae |
return 0;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
const struct pt_config *pt_enc_get_config(const struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
if (!encoder)
|
|
Packit |
b1f7ae |
return NULL;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return &encoder->config;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* Check the remaining space.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns zero if there are at least \@size bytes of free space available in
|
|
Packit |
b1f7ae |
* \@encoder's Intel PT buffer.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns -pte_eos if not enough space is available.
|
|
Packit |
b1f7ae |
* Returns -pte_internal if \@encoder is NULL.
|
|
Packit |
b1f7ae |
* Returns -pte_internal if \@encoder is not synchronized.
|
|
Packit |
b1f7ae |
*/
|
|
Packit |
b1f7ae |
static int pt_reserve(const struct pt_encoder *encoder, unsigned int size)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
const uint8_t *begin, *end, *pos;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder)
|
|
Packit |
b1f7ae |
return -pte_internal;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* The encoder is synchronized at all times. */
|
|
Packit |
b1f7ae |
pos = encoder->pos;
|
|
Packit |
b1f7ae |
if (!pos)
|
|
Packit |
b1f7ae |
return -pte_internal;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
begin = encoder->config.begin;
|
|
Packit |
b1f7ae |
end = encoder->config.end;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
pos += size;
|
|
Packit |
b1f7ae |
if (pos < begin || end < pos)
|
|
Packit |
b1f7ae |
return -pte_eos;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return 0;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* Return the size of an IP payload based on its IP compression.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns -pte_bad_packet if \@ipc is not a valid IP compression.
|
|
Packit |
b1f7ae |
*/
|
|
Packit |
b1f7ae |
static int pt_ipc_size(enum pt_ip_compression ipc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
switch (ipc) {
|
|
Packit |
b1f7ae |
case pt_ipc_suppressed:
|
|
Packit |
b1f7ae |
return 0;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_ipc_update_16:
|
|
Packit |
b1f7ae |
return pt_pl_ip_upd16_size;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_ipc_update_32:
|
|
Packit |
b1f7ae |
return pt_pl_ip_upd32_size;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_ipc_update_48:
|
|
Packit |
b1f7ae |
return pt_pl_ip_upd48_size;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_ipc_sext_48:
|
|
Packit |
b1f7ae |
return pt_pl_ip_sext48_size;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_ipc_full:
|
|
Packit |
b1f7ae |
return pt_pl_ip_full_size;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* Encode an integer value.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Writes the \@size least signifficant bytes of \@value starting from \@pos.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* The caller needs to ensure that there is enough space available.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns the updated position.
|
|
Packit |
b1f7ae |
*/
|
|
Packit |
b1f7ae |
static uint8_t *pt_encode_int(uint8_t *pos, uint64_t val, int size)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
for (; size; --size, val >>= 8)
|
|
Packit |
b1f7ae |
*pos++ = (uint8_t) val;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pos;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* Encode an IP packet.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Write an IP packet with opcode \@opc and payload from \@packet if there is
|
|
Packit |
b1f7ae |
* enough space in \@encoder's Intel PT buffer.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns the number of bytes written on success.
|
|
Packit |
b1f7ae |
*
|
|
Packit |
b1f7ae |
* Returns -pte_eos if there is not enough space.
|
|
Packit |
b1f7ae |
* Returns -pte_internal if \@encoder or \@packet is NULL.
|
|
Packit |
b1f7ae |
* Returns -pte_invalid if \@packet.ipc is not valid.
|
|
Packit |
b1f7ae |
*/
|
|
Packit |
b1f7ae |
static int pt_encode_ip(struct pt_encoder *encoder, enum pt_opcode op,
|
|
Packit |
b1f7ae |
const struct pt_packet_ip *packet)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
uint8_t *pos;
|
|
Packit |
b1f7ae |
uint8_t opc, ipc;
|
|
Packit |
b1f7ae |
int size, errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder || !packet)
|
|
Packit |
b1f7ae |
return pte_internal;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
size = pt_ipc_size(packet->ipc);
|
|
Packit |
b1f7ae |
if (size < 0)
|
|
Packit |
b1f7ae |
return size;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, /* opc size = */ 1 + size);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
/* We already checked the ipc in pt_ipc_size(). */
|
|
Packit |
b1f7ae |
ipc = (uint8_t) (packet->ipc << pt_opm_ipc_shr);
|
|
Packit |
b1f7ae |
opc = (uint8_t) op;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
pos = encoder->pos;
|
|
Packit |
b1f7ae |
*pos++ = opc | ipc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pt_encode_int(pos, packet->ip, size);
|
|
Packit |
b1f7ae |
return /* opc size = */ 1 + size;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_enc_next(struct pt_encoder *encoder, const struct pt_packet *packet)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
uint8_t *pos, *begin;
|
|
Packit |
b1f7ae |
int errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (!encoder || !packet)
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
pos = begin = encoder->pos;
|
|
Packit |
b1f7ae |
switch (packet->type) {
|
|
Packit |
b1f7ae |
case ppt_pad:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_pad);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_pad;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_psb: {
|
|
Packit |
b1f7ae |
uint64_t psb;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_psb);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
psb = ((uint64_t) pt_psb_hilo << 48 |
|
|
Packit |
b1f7ae |
(uint64_t) pt_psb_hilo << 32 |
|
|
Packit |
b1f7ae |
(uint64_t) pt_psb_hilo << 16 |
|
|
Packit |
b1f7ae |
(uint64_t) pt_psb_hilo);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, psb, 8);
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, psb, 8);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_psbend:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_psbend);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_psbend;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_ovf:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_ovf);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_ovf;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_fup:
|
|
Packit |
b1f7ae |
return pt_encode_ip(encoder, pt_opc_fup, &packet->payload.ip);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tip:
|
|
Packit |
b1f7ae |
return pt_encode_ip(encoder, pt_opc_tip, &packet->payload.ip);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tip_pge:
|
|
Packit |
b1f7ae |
return pt_encode_ip(encoder, pt_opc_tip_pge,
|
|
Packit |
b1f7ae |
&packet->payload.ip);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tip_pgd:
|
|
Packit |
b1f7ae |
return pt_encode_ip(encoder, pt_opc_tip_pgd,
|
|
Packit |
b1f7ae |
&packet->payload.ip);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tnt_8: {
|
|
Packit |
b1f7ae |
uint8_t opc, stop;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.tnt.bit_size >= 7)
|
|
Packit |
b1f7ae |
return -pte_bad_packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_tnt_8);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
stop = packet->payload.tnt.bit_size + pt_opm_tnt_8_shr;
|
|
Packit |
b1f7ae |
opc = (uint8_t) packet->payload.tnt.payload << pt_opm_tnt_8_shr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = opc | (1 << stop);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tnt_64: {
|
|
Packit |
b1f7ae |
uint64_t tnt, stop;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_tnt_64);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.tnt.bit_size >= pt_pl_tnt_64_bits)
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
stop = 1ull << packet->payload.tnt.bit_size;
|
|
Packit |
b1f7ae |
tnt = packet->payload.tnt.payload;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (tnt & ~(stop - 1))
|
|
Packit |
b1f7ae |
return -pte_invalid;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_tnt_64;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, tnt | stop, pt_pl_tnt_64_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_mode: {
|
|
Packit |
b1f7ae |
uint8_t mode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_mode);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
switch (packet->payload.mode.leaf) {
|
|
Packit |
b1f7ae |
default:
|
|
Packit |
b1f7ae |
return -pte_bad_packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_mol_exec:
|
|
Packit |
b1f7ae |
mode = pt_mol_exec;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.mode.bits.exec.csl)
|
|
Packit |
b1f7ae |
mode |= pt_mob_exec_csl;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.mode.bits.exec.csd)
|
|
Packit |
b1f7ae |
mode |= pt_mob_exec_csd;
|
|
Packit |
b1f7ae |
break;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case pt_mol_tsx:
|
|
Packit |
b1f7ae |
mode = pt_mol_tsx;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.mode.bits.tsx.intx)
|
|
Packit |
b1f7ae |
mode |= pt_mob_tsx_intx;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.mode.bits.tsx.abrt)
|
|
Packit |
b1f7ae |
mode |= pt_mob_tsx_abrt;
|
|
Packit |
b1f7ae |
break;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_mode;
|
|
Packit |
b1f7ae |
*pos++ = mode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_pip: {
|
|
Packit |
b1f7ae |
uint64_t cr3;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_pip);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
cr3 = packet->payload.pip.cr3;
|
|
Packit |
b1f7ae |
cr3 >>= pt_pl_pip_shl;
|
|
Packit |
b1f7ae |
cr3 <<= pt_pl_pip_shr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (packet->payload.pip.nr)
|
|
Packit |
b1f7ae |
cr3 |= (uint64_t) pt_pl_pip_nr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_pip;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, cr3, pt_pl_pip_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tsc:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_tsc);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_tsc;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, packet->payload.tsc.tsc,
|
|
Packit |
b1f7ae |
pt_pl_tsc_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_cbr:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_cbr);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_cbr;
|
|
Packit |
b1f7ae |
*pos++ = packet->payload.cbr.ratio;
|
|
Packit |
b1f7ae |
*pos++ = 0;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_tma: {
|
|
Packit |
b1f7ae |
uint16_t ctc, fc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_tma);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
ctc = packet->payload.tma.ctc;
|
|
Packit |
b1f7ae |
fc = packet->payload.tma.fc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (fc & ~pt_pl_tma_fc_mask)
|
|
Packit |
b1f7ae |
return -pte_bad_packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_tma;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, ctc, pt_pl_tma_ctc_size);
|
|
Packit |
b1f7ae |
*pos++ = 0;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, fc, pt_pl_tma_fc_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_mtc:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_mtc);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_mtc;
|
|
Packit |
b1f7ae |
*pos++ = packet->payload.mtc.ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_cyc: {
|
|
Packit |
b1f7ae |
uint8_t byte[pt_pl_cyc_max_size], index, end;
|
|
Packit |
b1f7ae |
uint64_t ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
ctc = (uint8_t) packet->payload.cyc.value;
|
|
Packit |
b1f7ae |
ctc <<= pt_opm_cyc_shr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
byte[0] = pt_opc_cyc;
|
|
Packit |
b1f7ae |
byte[0] |= (uint8_t) ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
ctc = packet->payload.cyc.value;
|
|
Packit |
b1f7ae |
ctc >>= (8 - pt_opm_cyc_shr);
|
|
Packit |
b1f7ae |
if (ctc)
|
|
Packit |
b1f7ae |
byte[0] |= pt_opm_cyc_ext;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
for (end = 1; ctc; ++end) {
|
|
Packit |
b1f7ae |
/* Check if the CYC payload is too big. */
|
|
Packit |
b1f7ae |
if (pt_pl_cyc_max_size <= end)
|
|
Packit |
b1f7ae |
return -pte_bad_packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
ctc <<= pt_opm_cycx_shr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
byte[end] = (uint8_t) ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
ctc >>= 8;
|
|
Packit |
b1f7ae |
if (ctc)
|
|
Packit |
b1f7ae |
byte[end] |= pt_opm_cycx_ext;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, end);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
for (index = 0; index < end; ++index)
|
|
Packit |
b1f7ae |
*pos++ = byte[index];
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_stop:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_stop);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_stop;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_vmcs:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_vmcs);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_vmcs;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos,
|
|
Packit |
b1f7ae |
packet->payload.vmcs.base >> pt_pl_vmcs_shl,
|
|
Packit |
b1f7ae |
pt_pl_vmcs_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_mnt:
|
|
Packit |
b1f7ae |
errcode = pt_reserve(encoder, ptps_mnt);
|
|
Packit |
b1f7ae |
if (errcode < 0)
|
|
Packit |
b1f7ae |
return errcode;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
*pos++ = pt_opc_ext;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext_ext2;
|
|
Packit |
b1f7ae |
*pos++ = pt_ext2_mnt;
|
|
Packit |
b1f7ae |
pos = pt_encode_int(pos, packet->payload.mnt.payload,
|
|
Packit |
b1f7ae |
pt_pl_mnt_size);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
encoder->pos = pos;
|
|
Packit |
b1f7ae |
return (int) (pos - begin);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
case ppt_unknown:
|
|
Packit |
b1f7ae |
case ppt_invalid:
|
|
Packit |
b1f7ae |
return -pte_bad_opc;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return -pte_bad_opc;
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_pad(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_pad;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_psb(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_psb;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_psbend(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_psbend;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tip(struct pt_encoder *encoder, uint64_t ip,
|
|
Packit |
b1f7ae |
enum pt_ip_compression ipc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tip;
|
|
Packit |
b1f7ae |
packet.payload.ip.ip = ip;
|
|
Packit |
b1f7ae |
packet.payload.ip.ipc = ipc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tnt_8(struct pt_encoder *encoder, uint8_t tnt, int size)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tnt_8;
|
|
Packit |
b1f7ae |
packet.payload.tnt.bit_size = (uint8_t) size;
|
|
Packit |
b1f7ae |
packet.payload.tnt.payload = tnt;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tnt_64(struct pt_encoder *encoder, uint64_t tnt, int size)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tnt_64;
|
|
Packit |
b1f7ae |
packet.payload.tnt.bit_size = (uint8_t) size;
|
|
Packit |
b1f7ae |
packet.payload.tnt.payload = tnt;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tip_pge(struct pt_encoder *encoder, uint64_t ip,
|
|
Packit |
b1f7ae |
enum pt_ip_compression ipc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tip_pge;
|
|
Packit |
b1f7ae |
packet.payload.ip.ip = ip;
|
|
Packit |
b1f7ae |
packet.payload.ip.ipc = ipc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tip_pgd(struct pt_encoder *encoder, uint64_t ip,
|
|
Packit |
b1f7ae |
enum pt_ip_compression ipc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tip_pgd;
|
|
Packit |
b1f7ae |
packet.payload.ip.ip = ip;
|
|
Packit |
b1f7ae |
packet.payload.ip.ipc = ipc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_fup(struct pt_encoder *encoder, uint64_t ip,
|
|
Packit |
b1f7ae |
enum pt_ip_compression ipc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_fup;
|
|
Packit |
b1f7ae |
packet.payload.ip.ip = ip;
|
|
Packit |
b1f7ae |
packet.payload.ip.ipc = ipc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_pip(struct pt_encoder *encoder, uint64_t cr3, uint8_t flags)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_pip;
|
|
Packit |
b1f7ae |
packet.payload.pip.cr3 = cr3;
|
|
Packit |
b1f7ae |
packet.payload.pip.nr = (flags & pt_pl_pip_nr) != 0;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_ovf(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_ovf;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_mode_exec(struct pt_encoder *encoder, enum pt_exec_mode mode)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_mode;
|
|
Packit |
b1f7ae |
packet.payload.mode.leaf = pt_mol_exec;
|
|
Packit |
b1f7ae |
packet.payload.mode.bits.exec = pt_set_exec_mode(mode);
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_mode_tsx(struct pt_encoder *encoder, uint8_t bits)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_mode;
|
|
Packit |
b1f7ae |
packet.payload.mode.leaf = pt_mol_tsx;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (bits & pt_mob_tsx_intx)
|
|
Packit |
b1f7ae |
packet.payload.mode.bits.tsx.intx = 1;
|
|
Packit |
b1f7ae |
else
|
|
Packit |
b1f7ae |
packet.payload.mode.bits.tsx.intx = 0;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
if (bits & pt_mob_tsx_abrt)
|
|
Packit |
b1f7ae |
packet.payload.mode.bits.tsx.abrt = 1;
|
|
Packit |
b1f7ae |
else
|
|
Packit |
b1f7ae |
packet.payload.mode.bits.tsx.abrt = 0;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tsc(struct pt_encoder *encoder, uint64_t tsc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tsc;
|
|
Packit |
b1f7ae |
packet.payload.tsc.tsc = tsc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_cbr(struct pt_encoder *encoder, uint8_t cbr)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_cbr;
|
|
Packit |
b1f7ae |
packet.payload.cbr.ratio = cbr;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_tma(struct pt_encoder *encoder, uint16_t ctc, uint16_t fc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_tma;
|
|
Packit |
b1f7ae |
packet.payload.tma.ctc = ctc;
|
|
Packit |
b1f7ae |
packet.payload.tma.fc = fc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_mtc(struct pt_encoder *encoder, uint8_t ctc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_mtc;
|
|
Packit |
b1f7ae |
packet.payload.mtc.ctc = ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_cyc(struct pt_encoder *encoder, uint32_t ctc)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_cyc;
|
|
Packit |
b1f7ae |
packet.payload.cyc.value = ctc;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_stop(struct pt_encoder *encoder)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_stop;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_vmcs(struct pt_encoder *encoder, uint64_t payload)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_vmcs;
|
|
Packit |
b1f7ae |
packet.payload.vmcs.base = payload;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
int pt_encode_mnt(struct pt_encoder *encoder, uint64_t payload)
|
|
Packit |
b1f7ae |
{
|
|
Packit |
b1f7ae |
struct pt_packet packet;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
packet.type = ppt_mnt;
|
|
Packit |
b1f7ae |
packet.payload.mnt.payload = payload;
|
|
Packit |
b1f7ae |
|
|
Packit |
b1f7ae |
return pt_enc_next(encoder, &packet);
|
|
Packit |
b1f7ae |
}
|